CSSCSS Logical Properties

CSS Logical Properties

Physical properties like margin-left or border-top describe a direction on screen — left is always left, top is always top, regardless of language. Logical properties describe a direction relative to the flow of content instead — "the side text starts from," "the side it ends at" — and that distinction stops being academic the moment your site needs to support a right-to-left language or a vertical writing mode.

Physical vs Logical: The Property Map

Physical (direction-specific)

Logical (flow-relative)

margin-left / margin-right

margin-inline-start / margin-inline-end

margin-top / margin-bottom

margin-block-start / margin-block-end

margin-left + margin-right together

margin-inline (shorthand for both inline sides)

margin-top + margin-bottom together

margin-block (shorthand for both block sides)

padding-left / padding-right

padding-inline-start / padding-inline-end

padding-top / padding-bottom

padding-block-start / padding-block-end

left / right (with positioning)

inset-inline-start / inset-inline-end

top / bottom (with positioning)

inset-block-start / inset-block-end

width / height

inline-size / block-size

border-left / border-right

border-inline-start / border-inline-end

text-align: left / right

text-align: start / end

In the default horizontal, left-to-right writing mode (English and most Western languages), inline maps to horizontal and block maps to vertical — so margin-inline-start behaves exactly like margin-left. The moment the writing mode or text direction changes, logical properties automatically flip to match, while physical properties stay pinned to the screen edge you named.

Why It Matters for Internationalization

Set dir="rtl" on the <html> element (or use a language like Arabic or Hebrew that requires it) and "start" flips to the right side of the screen. Recap: writing-mode covers vertical text direction, where inline and block axes rotate entirely. Logical properties track both of these automatically — physical properties do not, and require a whole parallel set of RTL overrides to correct.

Before / After: The Same Layout, Two Approaches

CSS
/* BEFORE: physical properties — wrong once dir="rtl" is set */
.card {
  margin-left: 16px;
  padding-left: 24px;
  padding-right: 12px;
  border-left: 4px solid #4a90d9;
  text-align: left;
}

/* Fixing RTL support the old way required a whole parallel ruleset: */
[dir="rtl"] .card {
  margin-left: 0;
  margin-right: 16px;
  padding-left: 12px;
  padding-right: 24px;
  border-left: none;
  border-right: 4px solid #4a90d9;
  text-align: right;
}

CSS
/* AFTER: logical properties — correct in LTR and RTL automatically,
   with zero [dir="rtl"] overrides needed */
.card {
  margin-inline-start: 16px;
  padding-inline: 24px 12px; /* start end */
  border-inline-start: 4px solid #4a90d9;
  text-align: start;
}

The logical version needs no [dir="rtl"] block at all — setting dir="rtl" anywhere up the document flips every one of those -inline-start / -inline-end values to the correct physical side automatically, because the browser recalculates which edge "start" currently means.

Shorthands Worth Knowing
  • margin-inline: 16px 24px sets start and end in one declaration (like margin-inline-start: 16px; margin-inline-end: 24px;).

  • margin-inline: 16px (a single value) sets both inline sides to the same value, same pattern for padding-inline and border-inline.

  • inset: 0 (all four logical insets at once) is the modern, direction-agnostic replacement for top: 0; right: 0; bottom: 0; left: 0;.

  • inline-size / block-size (and their min-/max- variants) replace width/height when you want sizing to respect writing mode too.

Prefer logical properties by default
Unless you have a specific reason to pin something to a literal screen edge (a decorative element that should always sit visually on the left, say), reach for the logical property by default on new projects. It costs nothing when your site only ever ships in one language and direction, and it means zero rework later if RTL support or a CMS-driven multi-language rollout shows up.