CSS logical properties replace physical directional properties (left, right, top, bottom) with logical equivalents that adapt to the document's writing direction. They're the modern approach for building interfaces that work in both left-to-right (LTR) and right-to-left (RTL) languages, as well as vertical writing modes.
The Problem with Physical Properties
Traditional CSS uses physical coordinates:
.card {
margin-left: 16px;
padding-right: 24px;
border-top: 1px solid #ccc;
text-align: left;
}
In Arabic or Hebrew (RTL), margin-left creates space on the wrong side. You'd need to override everything:
[dir="rtl"] .card {
margin-left: 0;
margin-right: 16px;
padding-right: 0;
padding-left: 24px;
text-align: right;
}
Logical properties handle this automatically.
The Logical Model
Logical properties use two axes:
- Inline: the direction text flows (left-right in English, right-left in Arabic, top-bottom in some Asian scripts)
- Block: the direction blocks stack (top-bottom in horizontal writing, right-left or left-right in vertical)
| Physical | Logical |
|---|---|
left |
inline-start |
right |
inline-end |
top |
block-start |
bottom |
block-end |
Margin, Padding, and Borders
/* Physical */
margin-left: 16px;
margin-right: 24px;
margin-top: 8px;
margin-bottom: 8px;
/* Logical equivalents */
margin-inline-start: 16px;
margin-inline-end: 24px;
margin-block-start: 8px;
margin-block-end: 8px;
Shorthand:
/* Physical */
margin: 8px 24px 8px 16px; /* top right bottom left */
/* Logical */
margin-block: 8px; /* block-start and block-end */
margin-inline: 16px 24px; /* inline-start and inline-end */
Border:
/* Physical */
border-top: 2px solid blue;
border-left: 1px solid gray;
/* Logical */
border-block-start: 2px solid blue;
border-inline-start: 1px solid gray;
Border radius:
/* Physical */
border-top-left-radius: 8px;
border-bottom-right-radius: 4px;
/* Logical */
border-start-start-radius: 8px; /* block-start + inline-start */
border-end-end-radius: 4px; /* block-end + inline-end */
Sizing
/* Physical */
width: 300px;
height: 200px;
max-width: 600px;
min-height: 100px;
/* Logical */
inline-size: 300px;
block-size: 200px;
max-inline-size: 600px;
min-block-size: 100px;
In horizontal writing mode, inline-size = width and block-size = height. In vertical writing mode, they swap.
Positioning
/* Physical */
.tooltip {
position: absolute;
top: 0;
left: 100%;
}
/* Logical */
.tooltip {
position: absolute;
inset-block-start: 0;
inset-inline-start: 100%;
}
The inset shorthand:
/* Physical */
top: 0; right: 0; bottom: 0; left: 0; /* fills container */
/* Logical */
inset: 0; /* same: works for all writing modes */
/* Or specific sides */
inset-block: 0; /* top + bottom */
inset-inline: 0; /* left + right */
Text Alignment
/* Physical */
text-align: left;
/* Logical */
text-align: start; /* start of inline direction */
text-align: end; /* end of inline direction */
start maps to left in LTR and right in RTL automatically.
Flexbox and Grid Already Use Logical Properties
Flexbox justify-content and align-items already adapt to writing-mode and direction:
.container {
display: flex;
justify-content: flex-start; /* always at inline-start */
}
This is why adding direction: rtl to a flex container automatically mirrors its children — the flex model is already logical.
Practical Example: A Card Component
Before (physical):
.card {
padding: 16px 24px;
margin-bottom: 16px;
border-left: 4px solid blue;
text-align: left;
}
[dir="rtl"] .card {
border-left: none;
border-right: 4px solid blue;
text-align: right;
}
After (logical):
.card {
padding-block: 16px;
padding-inline: 24px;
margin-block-end: 16px;
border-inline-start: 4px solid blue;
text-align: start;
}
/* No RTL override needed */
Browser Support
All major logical properties have excellent support in 2024:
-
margin-inline,margin-block,padding-inline,padding-block: 93%+ -
inset-inline,inset-block: 93%+ -
inline-size,block-size: 95%+ -
border-start-start-radius: 90%+
Firefox has had full logical property support since Firefox 69 (2019). There are no Firefox-specific gotchas here.
Check caniuse.com for current coverage.
Mixing Physical and Logical
You can mix them, but be careful with shorthand overrides:
.element {
margin-inline-start: 16px;
margin: 0; /* This RESETS margin-inline-start! */
}
Physical shorthands override logical properties. Use logical shorthands consistently or apply logical properties last.
When to Start Using Logical Properties
- New projects: use logical properties from the start
- RTL support needed: logical properties eliminate entire RTL override blocks
- Vertical writing mode: logical properties are essentially required
- Existing projects: migrate incrementally, one component at a time
The naming takes a moment to internalize — margin-inline-start instead of margin-left feels verbose at first. After a few days it becomes natural, and the reward is interfaces that handle RTL and other writing modes without any extra CSS.
For Firefox add-on and web extension work, logical properties ensure your extension's sidebar and popup UI adapts correctly when users have RTL system languages — no need to test-and-override each direction separately.
Top comments (0)