Manoj
Back to Blog
·6 min read

Understanding CSS Logical Properties for Modern Layouts

Most developers still use margin-left and padding-right out of habit. CSS logical properties are the modern replacement that makes your layouts direction-aware and future-proof.

cssfrontendi18n

Understanding CSS Logical Properties for Modern Layouts

If you're still writing margin-left, padding-right, and border-top in 2026, you're using a mental model from the early web. CSS logical properties have been fully supported in every major browser for years now, and they solve real problems that physical properties simply can't.

Let me show you why the switch matters and how to make it without overthinking things.

The Problem with Physical Properties

Physical properties like margin-left and padding-right are tied to the physical screen. Left is left. Right is right. Always.

That works fine when your entire audience reads left-to-right. But the moment your layout needs to support a right-to-left (RTL) language like Arabic, Hebrew, or Urdu, every single directional property breaks.

/* English (LTR): looks great */
/* Arabic (RTL): the icon spacing is now on the wrong side */
.nav-link {
  padding-left: 1.5rem;
  margin-right: 1rem;
  border-left: 3px solid blue;
}

To fix this with physical properties, you'd need to write overrides:

[dir="rtl"] .nav-link {
  padding-left: 0;
  padding-right: 1.5rem;
  margin-right: 0;
  margin-left: 1rem;
  border-left: none;
  border-right: 3px solid blue;
}

That's double the code for the same component. Now multiply that across an entire codebase.

Logical Properties: One Rule, Every Direction

Logical properties replace physical directions with flow-relative ones. Instead of left/right/top/bottom, you think in terms of inline (the direction text flows) and block (the direction content stacks).

.nav-link {
  padding-inline-start: 1.5rem;
  margin-inline-end: 1rem;
  border-inline-start: 3px solid blue;
}

This single rule works correctly in both LTR and RTL layouts. No overrides. No duplication. The browser resolves inline-start to "left" in English and "right" in Arabic automatically.

The Mental Model

The entire system comes down to two axes:

  • Inline axis = the direction text flows (horizontal in English)
  • Block axis = the direction blocks stack (vertical in English)

Each axis has a start and an end. That's it. Four directions instead of four compass points.

Margin & Padding:

  • margin-leftmargin-inline-start
  • margin-rightmargin-inline-end
  • margin-topmargin-block-start
  • margin-bottommargin-block-end
  • padding-leftpadding-inline-start
  • padding-rightpadding-inline-end
  • padding-toppadding-block-start
  • padding-bottompadding-block-end

Sizing:

  • widthinline-size
  • heightblock-size
  • max-widthmax-inline-size
  • max-heightmax-block-size

Positioning (inset):

  • topinset-block-start
  • bottominset-block-end
  • leftinset-inline-start
  • rightinset-inline-end

Shorthand Properties

Just like margin: 10px 20px sets vertical and horizontal, logical properties have their own shorthands:

/* Old way */
.card {
  margin-top: 1rem;
  margin-bottom: 1rem;
  margin-left: 2rem;
  margin-right: 2rem;
}

/* Logical shorthand */
.card {
  margin-block: 1rem;
  margin-inline: 2rem;
}

margin-block sets both block-start and block-end. margin-inline sets both inline-start and inline-end. Same pattern works for padding-block, padding-inline, border-block, border-inline, and inset-block/inset-inline.

You can also set start and end independently in the shorthand:

.sidebar {
  padding-inline: 2rem 1rem; /* start: 2rem, end: 1rem */
  margin-block: 0 1.5rem; /* start: 0, end: 1.5rem */
}

Logical Border Radius

Even border radius has logical equivalents:

/* Physical */
.card {
  border-top-left-radius: 1rem;
  border-top-right-radius: 1rem;
}

/* Logical */
.card {
  border-start-start-radius: 1rem;
  border-start-end-radius: 1rem;
}

The naming convention is border-{block}-{inline}-radius. So start-start means block-start + inline-start (top-left in LTR). Admittedly, this one reads a bit awkward, but it's consistent with the model.

Logical Properties for Positioning

The inset property family replaces top, right, bottom, and left:

/* Physical positioning */
.dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: auto;
}

/* Logical positioning */
.dropdown {
  position: absolute;
  inset-block-start: 100%;
  inset-inline-start: 0;
  inset-inline-end: auto;
}

And if you want to set all four inset values at once:

.overlay {
  position: absolute;
  inset: 0; /* Replaces top: 0; right: 0; bottom: 0; left: 0; */
}

You've probably already been using inset: 0 without realizing it's a logical property shorthand.

Sizing with Logical Properties

width and height have logical counterparts too:

.container {
  inline-size: 100%; /* width in horizontal writing mode */
  max-inline-size: 960px; /* max-width */
  block-size: auto; /* height */
  min-block-size: 100vh; /* min-height */
}

This matters for layouts that need to support vertical writing modes (Chinese, Japanese, Korean in traditional vertical layout). In vertical writing mode, inline-size maps to height instead of width.

Real-World Example: Navigation Component

Let's see a complete before/after for a typical navigation bar:

/* Before: Physical properties */
.nav {
  display: flex;
  padding: 0.75rem 1.5rem;
}

.nav-logo {
  margin-right: auto;
}

.nav-link {
  margin-left: 1.5rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  border-left: 1px solid #e5e7eb;
}
/* After: Logical properties */
.nav {
  display: flex;
  padding-block: 0.75rem;
  padding-inline: 1.5rem;
}

.nav-logo {
  margin-inline-end: auto;
}

.nav-link {
  margin-inline-start: 1.5rem;
  padding-inline: 0.75rem;
  border-inline-start: 1px solid #e5e7eb;
}

The logical version is barely longer, reads almost as clearly, and works in every text direction without a single override.

What About Tailwind?

If you're using Tailwind CSS (v3+), you already have logical property utilities:

<!-- Physical -->
<div class="ml-4 border-l-2 pr-6">
  <!-- Logical -->
  <div class="ms-4 border-s-2 pe-6"></div>
</div>

The convention: s for start, e for end. So ms-4 is margin-inline-start, pe-6 is padding-inline-end, and border-s-2 is border-inline-start-width.

In Tailwind v4, these are the recommended default over physical direction utilities.

"But I Don't Support RTL"

Fair point. Most projects don't. But here's why logical properties are still worth adopting:

  1. Future-proofing - adding RTL or vertical writing mode support later becomes trivial instead of a rewrite
  2. Consistency - using one system (logical) instead of mixing physical and logical is cleaner
  3. Flexbox and Grid already work this way - justify-content and align-items are already flow-relative. Logical properties make your spacing match your layout model
  4. It's the direction CSS is going - newer CSS features are designed with logical properties in mind

The cost of switching is near zero. The properties map 1:1. Your layouts look identical. You're just using better vocabulary.

When to Keep Using Physical Properties

There are legitimate cases where physical properties make more sense:

  • Decorative positioning that's genuinely tied to the viewport (a gradient that always fades to the right)
  • Scroll behaviors (scroll-margin-top for fixed header offset, there's no logical equivalent yet in practice)
  • Transform origins that relate to visual position, not text flow

If the style is about how something looks on screen regardless of language, physical properties are fine. If it's about layout relative to content flow, use logical.

Start Today

You don't need to rewrite your codebase. Just start using logical properties in new code. Over time, your muscle memory will shift from margin-left to margin-inline-start, and you'll wonder why you ever hard-coded directions in the first place.

The web is bigger than left-to-right. Your CSS should be too.