Tags: web-dev concept

Logical Properties

Date: 2026-09-27


margin-inline-start instead of margin-left: properties named by the direction text flows, not by the physical side of the screen. In a right-to-left language the layout mirrors itself with no extra CSS. In any other language they cost nothing, which makes them the better default.


Logical properties are flow-relative versions of the physical box properties (margin, padding, border, inset, size), named by the inline axis — the direction text runs in — and the block axis, the direction lines stack in. The physical side each one maps to depends on the element’s direction and writing-mode.

The mapping

ltr is left-to-right, rtl right-to-left — the values of the dir attribute.

                 English (ltr)       Arabic (rtl)        vertical (vertical-rl)
inline-start     left                right               top
inline-end       right               left                bottom
block-start      top                 top                 right
block-end        bottom              bottom              left

inline-size      width               width               height
block-size       height              height              width
margin-left: 1rem            →  margin-inline-start: 1rem
padding: 0 1rem              →  padding-inline: 1rem
padding-top / padding-bottom →  padding-block: 2rem 1rem
top: 0; left: 0              →  inset-block-start: 0; inset-inline-start: 0
width: 20rem                 →  inline-size: 20rem
text-align: left             →  text-align: start
border-top-left-radius       →  border-start-start-radius

What it buys

An icon before a label, with a gap on the text side:

/* physical: correct in English, wrong in Arabic — the gap ends up on the outside */
.icon { margin-right: 0.5rem; }
 
/* logical: the gap follows the text in both */
.icon { margin-inline-end: 0.5rem; }
ltr   [icon]␣Label            rtl   Label␣[icon]
                                         ↑ physical version puts the gap
                                           on the far side: ␣[icon]Label

For a site that will never be translated into a right-to-left language, the argument is weaker but still there: padding-inline and margin-block are simply shorter than the two-property pairs, and they say what the spacing is for — Spacing Systems.

What doesn’t flip

  • The shorthands stay physical. margin: 1rem 2rem 0 0 is still top/right/bottom/left. Use margin-block and margin-inline instead
  • Transforms and backgrounds. translateX(10px) and background-position: left are physical. Directional motion (a slide-in drawer) needs a :dir(rtl) override or a custom property holding the sign
  • Icons that mean a direction. Back arrows and “next” chevrons should mirror in right-to-left languages; logos, media play buttons and clocks shouldn’t. CSS can’t know which is which — that’s a per-icon decision
  • Flexbox and grid already follow direction. flex-direction: row and grid column order reverse with dir="rtl", so a layout built on them mostly mirrors already

Failure modes

  • Mixing physical and logical for the same side. margin-left and margin-inline-start set the same thing in left-to-right text, and the cascade picks whichever comes later. In a right-to-left language they’re different sides, and both apply
  • Adopting it halfway. A right-to-left locale on a half-migrated codebase looks more broken than a fully physical one would, because some parts mirror and some don’t. Lint for physical properties once you commit — Linting
  • Testing only in English. Set dir="rtl" on <html> in development to see every physical property that remains

Where it connects

  • The Box Model — the same box, named differently
  • Flexbox — logical by construction, which is why it predates this and still works