Skip to main content

CSS Logical Properties: Writing-Mode-Aware Layout

Logical properties replace physical direction keywords (left, right, top, bottom) with context-aware equivalents (inline-start, inline-end, block-start, block-end). They are the modern standard for building layouts that work correctly in all languages, including Right-to-Left (RTL) and vertical writing modes.

1. The Core Concept: Physical vs Logical

Physical (old): Logical (modern):
──────────────────────────────────────────────────────
left/right → inline-start / inline-end
top/bottom → block-start / block-end
width → inline-size
height → block-size

In English (horizontal, left-to-right):
inline = horizontal axis (left → right)
block = vertical axis (top → bottom)

In Arabic (horizontal, right-to-left):
inline = horizontal axis (right → left) — REVERSED
Writing a margin-left suddenly becomes a margin-right

In Japanese (vertical, right-to-left):
inline = vertical axis
block = horizontal axis — SWAPPED

2. Margin Logical Properties

/* Physical (avoid for international sites) */
margin-top: 1rem;
margin-right: 2rem;
margin-bottom: 1rem;
margin-left: 2rem;

/* Logical equivalents */
margin-block-start: 1rem; /* = margin-top in LTR */
margin-block-end: 1rem; /* = margin-bottom in LTR */
margin-inline-start: 2rem; /* = margin-left in LTR, margin-right in RTL */
margin-inline-end: 2rem; /* = margin-right in LTR, margin-left in RTL */

/* Shorthand — the most common usage */
margin-block: 1rem; /* = margin-top + margin-bottom */
margin-inline: 2rem; /* = margin-left + margin-right */

/* Two values: start | end */
margin-block: 1rem 2rem; /* block-start: 1rem, block-end: 2rem */
margin-inline: 0 auto; /* inline-start: 0, inline-end: auto → right-align trick */

/* Auto centering (logical — works in all writing modes) */
margin-inline: auto; /* Centers horizontally in LTR, also works in RTL */
/* Replace: margin-left: auto; margin-right: auto; */

3. Padding Logical Properties

/* Same pattern as margin */
padding-block: 1.5rem; /* top + bottom padding */
padding-inline: 1rem; /* left + right padding */

padding-block-start: 1rem; /* top */
padding-block-end: 2rem; /* bottom */
padding-inline-start: 1.5rem; /* left (in LTR) */
padding-inline-end: 1.5rem; /* right (in LTR) */

/* Practical examples */
.o-container {
padding-inline: clamp(1rem, 4vw, 2rem); /* Responsive horizontal padding */
}

.c-nav__link {
padding-block: 0.5rem; /* Vertical padding */
padding-inline: 1rem; /* Horizontal padding */
}

.c-section {
padding-block: clamp(3rem, 8vw, 8rem); /* Responsive vertical spacing */
}

4. Border Logical Properties

/* Logical border shorthand */
border-block: 1px solid var(--color-border); /* top + bottom */
border-inline: 1px solid var(--color-border); /* left + right */
border-block-start: 1px solid var(--color-border); /* top */
border-block-end: 1px solid var(--color-border); /* bottom */
border-inline-start: 1px solid var(--color-border); /* left in LTR */
border-inline-end: 1px solid var(--color-border); /* right in LTR */

/* Practical: accent left border (or right in RTL) */
.c-alert { border-inline-start: 4px solid var(--color-primary); }

/* Dividers */
.c-nav__item + .c-nav__item {
border-inline-start: 1px solid var(--color-border);
}

5. Size Logical Properties

/* Width and height → inline-size and block-size */

/* Physical → Logical */
width: 1200px;inline-size: 1200px;
height: 400px;block-size: 400px;
max-width: 1200px;max-inline-size: 1200px;
min-height: 100dvh;min-block-size: 100dvh;

/* Practical examples */
.o-container {
max-inline-size: 1200px; /* max-width in logical */
margin-inline: auto;
}

.c-hero {
min-block-size: 100dvh; /* min-height in logical */
}

.c-sidebar {
inline-size: 280px; /* width in logical */
max-inline-size: 100%; /* Responsive maximum */
}

/* Note: In standard horizontal LTR/RTL writing:
inline-size = width, block-size = height
They switch in vertical writing modes (rare but correct) */

6. Position Logical Properties

/* Physical offset → Logical offset */
top: 0;inset-block-start: 0;
bottom: 0;inset-block-end: 0;
left: 0;inset-inline-start: 0;
right: 0;inset-inline-end: 0;

/* The `inset` shorthand — the most useful */
inset: 0; /* = top:0; right:0; bottom:0; left:0 — fill parent */
inset: 0 0 auto auto; /* top right bottom left — same "clock" as margin/padding */
inset-block: 0; /* top + bottom = 0 */
inset-inline: 0; /* left + right = 0 */

/* Practical: overlay that covers its positioned parent */
.c-overlay {
position: absolute;
inset: 0; /* Replaces: top:0; right:0; bottom:0; left:0 */
background: rgba(0,0,0,0.5);
}

/* Modal backdrop */
.c-modal__backdrop {
position: fixed;
inset: 0;
z-index: var(--z-overlay);
}

/* Center-align with position absolute */
.c-badge-corner {
position: absolute;
inset-block-start: -0.5rem;
inset-inline-end: -0.5rem;
}
/* In LTR: positions at top-right. In RTL: positions at top-left. */

7. Scroll and Overflow Logical Properties

/* Scroll margin / scroll padding use logical versions too */
scroll-margin-block-start: 80px; /* Offset from top when snapping */
scroll-padding-block-start: 80px; /* Container scroll snap offset */

/* Text alignment */
text-align: start; /* left in LTR, right in RTL — matches reading direction */
text-align: end; /* right in LTR, left in RTL */
/* Prefer 'start'/'end' over 'left'/'right' for user-facing text alignment */

/* Float logical */
float: inline-start; /* = float:left in LTR, float:right in RTL */
float: inline-end; /* = float:right in LTR */

8. When to Use Logical Properties

Always Use Logical For:

/* ✅ Use logical: centering, consistent spacing */
margin-inline: auto; /* Center horizontally */
padding-block: 1rem; /* Vertical padding */
padding-inline: 1.5rem; /* Horizontal padding */

/* ✅ Use logical: directional accents that should flip in RTL */
border-inline-start: 4px solid var(--color-primary); /* Left accent */

/* ✅ Use logical: absolute positioning */
position: absolute;
inset: 0; /* Fill container */
inset-block-start: 1rem; /* Top offset */
inset-inline-end: 1rem; /* Right offset (flips in RTL) */

Physical Is Still Fine For:

/* ✅ Physical OK: when direction doesn't need to flip */
border-radius: 1rem; /* Corners are symmetric → no direction */
box-shadow: 0 4px 12px ...; /* Visual effect → no direction needed */
background-position: center; /* No direction flip needed */

/* ✅ Physical OK: explicit directional intent */
/* "This badge is always in the top-right corner, regardless of language" */
.c-badge { top: -0.5rem; right: -0.5rem; }
/* If you WANT it to flip in RTL, switch to logical:
inset-block-start: -0.5rem; inset-inline-end: -0.5rem; */

9. Browser Support

Property GroupChromeFirefoxSafariEdge
margin-block/inline✅ 87✅ 66✅ 14.1✅ 87
padding-block/inline✅ 87✅ 66✅ 14.1✅ 87
inset✅ 87✅ 87✅ 14.1✅ 87
inline-size/block-size✅ 87✅ 66✅ 14.1✅ 87
border-block/inline✅ 87✅ 66✅ 14.1✅ 87
Overall~96%

Logical properties are safe to use in production today.


10. Quick Conversion Cheat Sheet

Physical (old)Logical (modern)
margin-topmargin-block-start
margin-bottommargin-block-end
margin-leftmargin-inline-start
margin-rightmargin-inline-end
margin-top + margin-bottommargin-block
margin-left + margin-rightmargin-inline
padding-top/bottompadding-block
padding-left/rightpadding-inline
border-topborder-block-start
border-leftborder-inline-start
widthinline-size
heightblock-size
max-widthmax-inline-size
min-heightmin-block-size
top/right/bottom/left: 0inset: 0
left: 1reminset-inline-start: 1rem
text-align: lefttext-align: start

11. AI and Logical Properties

AI models (especially newer ones) increasingly default to logical properties. Here's how to guide them:

For RTL-aware projects:
"Use CSS logical properties for all spacing and positioning:
margin-inline instead of margin-left/right,
padding-block instead of padding-top/bottom,
inset instead of top/right/bottom/left,
inline-size instead of width,
block-size instead of height."

For LTR-only English sites (acceptable to use physical):
"Use standard physical properties (width, height, margin-left, etc.)
— this site is English-only and does not need RTL support."