CSS Logical Properties
Replace physical directions (top/right/bottom/left) with flow-relative logical properties (block/inline) so layouts automatically adapt to different writing modes and text directions, including right-to-left languages, without extra CSS.
Properties like margin-left and border-top assume text always flows left-to-right, top-to-bottom — an assumption baked into English but not true of Arabic, Hebrew, or traditional vertical Japanese text. CSS logical properties describe layout in terms of the flow of content instead of fixed screen directions, so the same CSS automatically works correctly no matter what writing mode or text direction the page uses.
Block vs inline: the two flow-relative axes
Logical properties replace the four physical directions with two flow-relative axes. The inline axis runs in the direction text flows within a line — left-to-right in English, right-to-left in Arabic, top-to-bottom in vertical Japanese. The block axis runs in the direction blocks stack — normally top-to-bottom, but it can rotate with the writing mode too.
In standard English left-to-right, top-to-bottom text: inline-start maps to the physical left, inline-end maps to the physical right, block-start maps to the physical top, and block-end maps to the physical bottom. Change the page's writing direction, and those mappings rotate automatically — the CSS itself doesn't change at all.
Logical property names you'll actually use
Most physical properties have a direct logical equivalent. The naming pattern replaces top/right/bottom/left with block-start/inline-end/block-end/inline-start, and there are convenient shorthand axis properties too.
• margin-inline-start / margin-inline-end — replace margin-left / margin-right (in LTR) • margin-block-start / margin-block-end — replace margin-top / margin-bottom • margin-inline / margin-block — shorthand setting both start and end on that axis at once • padding-inline, padding-block — same pattern for padding • inset-inline-start, inset-inline-end, inset-block-start, inset-block-end — replace top/right/bottom/left for positioned elements • inset-inline, inset-block — shorthand versions of the above • border-inline-start, border-block-end, and similar for individual border sides • inline-size and block-size — replace width and height in a flow-relative way
Writing modes
The writing-mode property controls which physical direction is 'block' and which is 'inline'. horizontal-tb is the default (blocks stack top-to-bottom, inline flows left-to-right or right-to-left depending on direction). vertical-rl and vertical-lr rotate the whole layout for vertical scripts. The direction property (ltr or rtl) controls which way the inline axis flows within horizontal-tb.
You rarely set writing-mode by hand for a typical multilingual website — it's more commonly relevant to specific vertical-text design work — but direction: rtl is exactly what an Arabic or Hebrew version of a site sets, and logical properties are what makes the rest of your CSS respond to that automatically.
The internationalization payoff
This is the real reason logical properties exist: a layout written entirely with logical properties requires zero extra CSS to support right-to-left languages. If you wrote padding-left: 20px on a 'next' button's icon, that padding stays stubbornly on the left even when the whole page flips to RTL, putting the padding on the wrong side visually. If you instead wrote padding-inline-start: 20px, the browser automatically applies it to whichever side 'start' means for the current direction — left in LTR, right in RTL — with no separate RTL stylesheet, no [dir="rtl"] overrides, and no JavaScript.
Physical vs logical property mapping (default LTR)
inline-size replaces width and block-size replaces height in flow-relative terms margin-inline / padding-inline / inset-inline are two-value shorthands for the start+end pair on that axis In the default horizontal-tb, ltr writing mode, logical and physical properties behave identically — the difference only shows once direction or writing-mode changes
/* Physical (assumes left-to-right) */
.card-old {
margin-left: 16px;
padding-top: 8px;
border-right: 1px solid #ddd;
width: 300px;
}
/* Logical equivalent (adapts to writing direction automatically) */
.card-new {
margin-inline-start: 16px;
padding-block-start: 8px;
border-inline-end: 1px solid #ddd;
inline-size: 300px;
}
/* Shorthand axis properties */
.box {
margin-inline: 1rem; /* sets both inline-start and inline-end */
padding-block: 0.5rem; /* sets both block-start and block-end */
}
/* Switching direction for an RTL page needs no extra CSS */
html[dir="rtl"] {
/* .card-new above already adapts correctly, automatically */
}Code Examples
In an LTR page (English, most European languages) this puts 8px of space to the right of the icon, before the button label. In an RTL page (Arabic, Hebrew), the exact same rule automatically puts the 8px on the left instead, because inline-end tracks the end of the reading direction rather than a fixed physical side.
Written entirely with logical properties, this sidebar's 260px width, its border, and its padding all correctly reposition themselves if the page's writing direction changes — the border stays on the 'reading end' side of the sidebar rather than a hardcoded physical right, for instance.
This looks fine in English, but in an RTL layout, readers expect the accent border and the extra padding on the side where reading starts — the right side in RTL — not hardcoded to physical left/right. This rule would need a separate [dir="rtl"] override to look correct, which is exactly the duplicated maintenance burden logical properties eliminate.
Common mistake: Hardcoding physical left/right instead of using inline-start/inline-end.
.btn-icon {
margin-inline-end: 8px;
}.sidebar {
inline-size: 260px;
block-size: 100%;
padding-inline: 1.5rem;
border-inline-end: 1px solid #e0e0e0;
}.card {
padding-left: 20px;
border-right: 4px solid #3366ff;
}Physical vs logical axes
Logical property names stay the same across writing directions; it's the physical side they map to that changes.
LTR, horizontal-tb (English):
block-start (top)
^
inline-start | inline-end
(left) <---+---> (right)
v
block-end (bottom)
RTL, horizontal-tb (Arabic):
block-start (top)
^
inline-end | inline-start
(left) <---+---> (right)
v
block-end (bottom)
(inline-start/end SWAP sides automatically — your CSS doesn't change)Important Rules
Logical properties describe direction relative to content flow (block/inline), not fixed screen position (top/right/bottom/left).
In the default horizontal-tb + ltr writing mode, inline-start = left, inline-end = right, block-start = top, block-end = bottom.
inline-size and block-size are the logical equivalents of width and height.
margin-inline, padding-inline, and inset-inline are shorthands that set both the start and end value on the inline axis at once (same for -block).
A layout written entirely in logical properties adapts to direction: rtl or a different writing-mode automatically, with no duplicated CSS.
When this matters for EngiLipi
EngiLipi is an educational platform with a global audience, and course content pages, code editor panels, and lesson-navigation sidebars are all candidates for eventual right-to-left language support. Components built with logical properties (padding-inline, margin-block, inset-inline-start) from the start need no rework later — flipping the top-level direction attribute is enough to correctly mirror the whole layout, rather than requiring a parallel RTL stylesheet maintained alongside the LTR one..alert-icon { margin-right: 10px; }.alert-icon { margin-inline-end: 10px; } margin-right hardcodes the physical right side. In an RTL layout the spacing would end up on the wrong side of the icon relative to the reading direction. margin-inline-end always lands on the 'end' side of reading flow, whichever physical direction that is..box { width: 100%; height: 200px; padding-left: 12px; }.box { inline-size: 100%; block-size: 200px; padding-inline-start: 12px; }
Mixing physical width/height/padding-left with an otherwise internationalized layout reintroduces exactly the hardcoded-direction problem logical properties are meant to solve — pick one system consistently within a component.
[True / False] True or False: A layout built entirely with logical properties (margin-inline, padding-block, inline-size, etc.) will automatically render correctly for a right-to-left language once the page's direction is set to rtl, with no additional CSS overrides needed. A. True B. False
A. True — True — that's the entire point of logical properties. Because inline-start/inline-end (and the block equivalents) are defined relative to the content's reading direction rather than a fixed physical side, they automatically re-map when direction switches to rtl, eliminating the need for a separate [dir="rtl"] override stylesheet.
Rewrite this physical CSS using logical properties:.tag { width: 80px; margin-left: 6px; padding-top: 4px; padding-bottom: 4px; border-left: 3px solid teal; }.tag { inline-size: 80px; margin-inline-start: 6px; padding-block: 4px; border-inline-start: 3px solid teal; } width becomes inline-size; margin-left becomes margin-inline-start; top/bottom padding becomes the padding-block shorthand; border-left becomes border-inline-start.