Lesson 15
Logical Properties - Writing-Mode-Aware Layout
Traditional CSS uses physical directions: top, right, bottom, left. These are tied to the screen - they always mean the same thing regardless of language direction. Logical properties replace them with flow-relative directions that adapt to writing mode and text direction.
The mental model
Instead of thinking in physical directions (top/right/bottom/left), think in two axes:
- Block axis - the direction blocks stack (paragraphs, divs). In English: top → bottom.
- Inline axis - the direction text flows. In English: left → right. In Arabic: right → left.
The principle: "Block" = the axis things stack on. "Inline" = the axis text flows on. "Start" and "end" replace "top/left" and "bottom/right." When the writing mode changes, logical properties automatically flip - physical properties don't.
The mapping - physical → logical
| Physical (old) | Logical (new) | In English LTR |
|---|---|---|
margin-top |
margin-block-start |
= top |
margin-bottom |
margin-block-end |
= bottom |
margin-left |
margin-inline-start |
= left (= right in RTL) |
margin-right |
margin-inline-end |
= right (= left in RTL) |
width |
inline-size |
= width |
height |
block-size |
= height |
top |
inset-block-start |
= top |
left |
inset-inline-start |
= left (= right in RTL) |
border-top |
border-block-start |
= top |
text-align: left |
text-align: start |
= left (= right in RTL) |
Shorthand properties
Logical properties also have two-value shorthands for setting both sides of an axis at once:
margin-block sets top + bottom. margin-inline sets left + right (in LTR).
margin-inline: 2rem (left+right)
<!-- HTML -->
<div class="box">Content</div>
.box {
margin-block: 1rem; /* = margin-top + margin-bottom */
margin-inline: 2rem; /* = margin-left + margin-right (flips in RTL) */
padding-block: 0.5rem; /* = padding-top + padding-bottom */
padding-inline: 1rem; /* = padding-left + padding-right */
border-inline: 1px solid gray; /* left + right borders */
inline-size: 300px; /* = width */
block-size: auto; /* = height */
}
Live demo: LTR vs RTL
Same CSS, different direction - logical properties adapt automatically
direction: ltr (English)
direction: rtl (Arabic)
.callout {
border-inline-start: 4px solid blue; /* left in LTR, right in RTL */
padding-inline-start: 1rem; /* same - adapts with direction */
padding-block: 0.5rem; /* top + bottom - always the same */
}
Why this matters even if you only build English sites:
- Logical properties are shorter to write in many cases (
margin-inline: autovsmargin-left: auto; margin-right: auto) - Future-proofs your CSS for i18n - if your app ever needs RTL support, it works out of the box
- Aligns with how Flexbox and Grid already think (they use start/end, not left/right)
- Modern linters (Stylelint) increasingly recommend logical properties as the default
The centering shorthand
margin-inline: auto centers horizontally - shorter than margin-left: auto + margin-right: auto
<!-- HTML -->
<div class="centered">Content</div>
.centered {
inline-size: 200px; /* = width: 200px */
margin-inline: auto; /* = margin-left: auto; margin-right: auto */
/* Centers horizontally - and flips correctly in RTL */
}
Inset - logical positioning
For positioned elements, logical equivalents of top/right/bottom/left:
inset-inline-start replaces "left" for positioned elements
<!-- HTML -->
<div class="parent">
<div class="positioned">Badge</div>
</div>
.positioned {
position: absolute;
inset-block-start: 0.5rem; /* = top */
inset-inline-start: 0.5rem; /* = left (= right in RTL) */
}
/* Shorthand for all four: */
.overlay {
position: absolute;
inset: 0; /* = top: 0; right: 0; bottom: 0; left: 0 */
}
border-radius - logical values
Even border-radius has logical equivalents:
/* Physical */
border-top-left-radius: 8px;
/* Logical */
border-start-start-radius: 8px; /* block-start + inline-start corner */
border-start-end-radius: 8px; /* block-start + inline-end corner */
border-end-start-radius: 8px; /* block-end + inline-start corner */
border-end-end-radius: 8px; /* block-end + inline-end corner */
In practice, border-radius: 8px (uniform) is used far more often than individual corners, so the logical versions of border-radius are less common.
When to use logical vs physical
| Use logical when... | Use physical when... |
|---|---|
| Spacing/alignment relates to text flow | Position is tied to the viewport (e.g. "stick to the screen bottom") |
| Building reusable components | Decorative effects not related to content direction |
| Your app may need RTL support (now or later) | Explicitly positioning relative to the physical screen |
Practical rule: Default to logical properties for everything content-related (margin, padding, border, sizing). Only use physical properties when you genuinely mean "the physical left edge of the screen" regardless of language direction.
Browser support
All logical properties: Chrome 87+, Safari 14.1+, Firefox 66+. Fully production-ready.
Retrieval check
Question 1
What does "block" mean in logical properties?
Question 2
In an RTL language, what physical side does margin-inline-start apply to?
Question 3
What is the logical equivalent of width?
Question 4
What does margin-inline: auto do?
Question 5
What does inset: 0 do on a positioned element?