5 min read

CSS Logical Properties: Stop Writing margin-left, Start Writing margin-inline-start

Here's a question most CSS developers can't answer about their own stylesheet: what does margin-left even mean? On a left-to-right page, it means "the left edge." But rotate the writing direction and "left" stops being a meaningful concept. The physical properties (left, right, top, bottom) describe the screen. Logical properties describe the content flow — and content flow is what layout is actually about.

Logical properties are the modern way to write spacing, sizing, and borders. They're supported everywhere, they make RTL support nearly free, and they're one of those upgrades you do once and never think about again.

The mental model: inline and block

Every element has two logical axes:

  • Inline axis — the direction text flows. Left-to-right in English, right-to-left in Arabic and Hebrew.
  • Block axis — the direction blocks stack. Top-to-bottom in most languages, with exceptions like Japanese vertical text.

Physical properties are relative to the screen. Logical properties are relative to these axes:

margin-left     → margin-inline-start   /* start of the inline axis */
margin-right    → margin-inline-end     /* end of the inline axis */
margin-top      → margin-block-start    /* start of the block axis */
margin-bottom   → margin-block-end      /* end of the block axis */

padding-left    → padding-inline-start
border-left     → border-inline-start
width           → inline-size
height          → block-size

The full mapping is large, but the pattern is one line to remember: physical "left" becomes logical "inline-start," physical "top" becomes "block-start." The rest falls out of that.

Why you should switch

1. RTL support stops being a rewrite

This is the headline reason. A sidebar with margin-left: 1rem needs a different rule in a right-to-left layout. With margin-inline-start: 1rem, the browser places the margin on the correct side automatically — no [dir="rtl"] overrides, no mirrored stylesheet.

For products that ship in Arabic, Hebrew, or any RTL language, logical properties aren't a nicety; they're the difference between "localization" and "building the layout twice."

2. Your "left" might be someone's "right"

Even without full RTL support, mixing direction in a UI — a rail, a drawer, a flipped dashboard — becomes far less painful when you're describing content flow instead of screen coordinates.

3. It documents intent

margin-inline-start tells the reader "this spacing is about content flow, not screen position." That's a real signal in a codebase, and it makes refactoring safer.

Practical gotchas

1. Some properties have no logical version yet

border-radius got logical longhands (border-start-start-radius, etc.) that are verbose and rarely worth it. transform and position offsets are also still physical in most cases. Use logical properties where the mapping is clean (margin, padding, inset, size) and don't force it where the names get absurd.

2. inset is the shorthand that helps

/* physical */
top: 0; right: 0; bottom: 0; left: 0;
/* logical */
inset: 0;

inset-block: 0;     /* top and bottom */
inset-inline: 0;    /* left and right */

For absolute positioning, inset-inline and inset-block cover most cases and read much better than four physical properties.

3. Default writing mode still works

In a default writing-mode: horizontal-tb context, logical and physical properties produce identical results for LTR content. The switch is invisible to your current users — it only changes behavior when direction or writing mode changes. That's the whole point: you future-proof without changing today's output.

Browser support

Logical properties have been baseline since 2020 (Chrome 87, Safari 14.1, Firefox 66). There's no compatibility excuse left — every browser your users run supports them, and the fallback story is just "use physical properties if you need ancient support."

Where it sits in the modern CSS stack

Logical properties are the quiet foundation of modern CSS. They're less flashy than container queries or :has(), but they change how every layout you write behaves. Pair them with cascade layers for priority and you have a layout system that's direction-aware and specificity-sane.

When I do a migration like this, I save the mapping table and the patterns that work in Snippet Ark — the "physical to logical" cheat sheet is exactly the kind of thing you don't want to re-derive mid-project.

The bottom line

Logical properties describe layout the way layout actually works — as content flowing through axes, not coordinates on a screen. They cost nothing to adopt, make RTL support a rounding error instead of a project, and force you to think about writing direction from day one. If you only do one CSS modernization this year, do this one first.