CSS logical properties let you describe layout in terms of flow rather than hard-coded sides like left, right, top, and bottom. In other words, instead of saying “put space on the left,” you can say “put space at the inline start,” and the browser maps that to the correct physical side based on the element’s writing mode and direction. That flow-relative behavior is the whole superpower here.

CSS uses the ideas of inline and block axes. The inline axis is the direction text flows in a line, and the block axis is the direction blocks stack. Those axes can change when you change direction or writing-mode, which is exactly why logical properties are so useful for internationalized and adaptable layouts.

What are CSS logical properties?

CSS logical properties are flow-relative versions of familiar properties like margin, padding, width, height, top, left, and friends.

Instead of tying your design to physical directions, they tie it to reading flow:

  • inline = the direction text runs
  • block = the direction blocks stack
  • start and end = the beginning and end of that axis

So, rather than writing margin-left, you can write margin-inline-start. In a left-to-right layout, that usually behaves like left. In a right-to-left layout, it usually behaves like right. That is much smarter, and much less stubborn.

Physical vs logical

Here is the big mental switch:

  • Physical properties say exactly where: left, right, top, bottom
  • Logical properties say where in the reading flow: inline-start, inline-end, block-start, block-end
.card {
  margin-left: 2rem;
}
.card {
  margin-inline-start: 2rem;
}
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  display: grid;
  gap: 1rem;
  font-family: system-ui, sans-serif;
}

.card {
  inline-size: 220px;
  padding: 1rem;
  border: 3px solid #111;
  border-radius: 0.75rem;
  background: #f4f4f4;
}
I am a card

In the first snippet, the space is always on the left. In the second, the space is at the start of the inline axis. That makes the second version more adaptable.

Understanding inline and block

Beginners often learn CSS with width, height, left, and right first, so logical properties can feel a little upside down at first. The trick is to stop thinking like a page is permanently horizontal and English-shaped.

Inline axis

The inline axis is the direction text flows within a line.

  • In English, it usually goes left to right
  • In Arabic or Hebrew, it usually goes right to left
  • In vertical writing modes, it can run top to bottom

Block axis

The block axis is the direction block-level content stacks.

  • In common horizontal writing, blocks stack top to bottom
  • In some vertical writing modes, blocks can stack horizontally

CSS writing modes define that behavior, and direction affects text flow for left-to-right versus right-to-left scripts.

writing-mode:
.demo {
  writing-mode: horizontal-tb;
}
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  font-family: system-ui, sans-serif;
  font-size: 1.1rem;
  inline-size: 220px;
  padding: 1rem;
  border: 3px solid #111;
  border-radius: 0.75rem;
  background: #f6f6f6;
}

.demo strong {
  background: #dfe8ff;
}
Logical properties follow the writing flow.

Toggle the writing mode and you can immediately see why “left” and “right” are not always the best way to describe layout.

Why logical properties are worth learning

They are worth learning because they make CSS more flexible, more international-friendly, and often easier to maintain.

Better international support

A layout built with logical properties adapts better to right-to-left languages and different writing modes because spacing and alignment follow the content flow instead of being frozen to one physical side.

Clearer intent

padding-inline tells me “horizontal-ish space along the text flow.” That is often more meaningful than padding-left and padding-right.

Fewer overrides

When your site later needs dir="rtl", you usually do not want to rewrite dozens of left/right rules. Logical properties reduce that future headache.

Logical margin and padding

This is the easiest and most useful place to start.

Margin and padding cheat sheet

  • margin-inline-start
  • margin-inline-end
  • margin-block-start
  • margin-block-end
  • margin-inline
  • margin-block
  • padding-inline-start
  • padding-inline-end
  • padding-block-start
  • padding-block-end
  • padding-inline
  • padding-block

Using margin-inline-start

This is the logical version of “give me space at the beginning of the text direction.”

direction:
.row {
  direction: ltr;
}

.badge {
  margin-inline-start: 2rem;
}
*,
::before,
::after {
  box-sizing: border-box;
}

.row {
  font-family: system-ui, sans-serif;
  border: 3px solid #111;
  border-radius: 0.75rem;
  padding: 1rem;
  background: #fafafa;
}

.badge {
  display: inline-block;
  padding: 0.5rem 0.8rem;
  border-radius: 999px;
  background: #111;
  color: #fff;
}
Label New

In ltr, the badge moves away from the left side of the inline axis. In rtl, that same rule moves it away from the right side instead. That is exactly the kind of smart behavior logical properties are built for.

Using padding-inline and padding-block

These shorthands are lovely. Use them when you want padding along one axis without thinking about the physical sides.

.button {
  padding-inline: 24px 24px;
}
*,
::before,
::after {
  box-sizing: border-box;
}

.button {
  display: inline-block;
  padding-block: 0.9rem;
  border: 3px solid #111;
  border-radius: 999px;
  font: 700 1rem/1 system-ui, sans-serif;
  background: #ffe38a;
}

Notice how the snippet only contains the part we are teaching: padding-inline. Everything else lives in the default CSS where it belongs.

Logical borders

Borders also have logical versions, and they are very handy when you want to decorate the “start” or “end” side of content.

  • border-inline-start
  • border-inline-end
  • border-block-start
  • border-block-end
  • border-inline
  • border-block

MDN describes properties such as border-inline-start as logical shorthands whose physical side depends on writing mode and direction.

direction:
.note {
  direction: ltr;
}

.note {
  border-inline-start: 12px solid tomato;
}
*,
::before,
::after {
  box-sizing: border-box;
}

.note {
  font-family: system-ui, sans-serif;
  padding: 1rem;
  border-block: 3px solid #111;
  border-inline-end: 3px solid #111;
  border-radius: 0.75rem;
  background: #fff4ef;
  max-inline-size: 28rem;
}
Important notes can use a logical start border.

What about border radius?

Border radius has logical corner properties too. They look a little dramatic at first, but they are not scary once you decode the names:

  • border-start-start-radius
  • border-start-end-radius
  • border-end-start-radius
  • border-end-end-radius

These name the corner by combining block/inline start/end positions rather than top-left or bottom-right. That means the rounded corner can move appropriately when the writing flow changes.

.speech {
  border-start-start-radius: 2rem;
  border-start-end-radius: 0.4rem;
  border-end-start-radius: 0.4rem;
  border-end-end-radius: 2rem;
}
*,
::before,
::after {
  box-sizing: border-box;
}

.speech {
  max-inline-size: 18rem;
  padding: 1rem 1.2rem;
  border: 3px solid #111;
  font-family: system-ui, sans-serif;
  background: #eef7ff;
}
Hello from a logically rounded box.

Logical sizing

This is another excellent category to use every day.

  • inline-size instead of width
  • block-size instead of height
  • min-inline-size, max-inline-size
  • min-block-size, max-block-size

MDN’s sizing guide explains these as logical equivalents to physical dimensions, mapped through writing mode.

inline-size vs width

In a typical horizontal writing mode, inline-size often feels like width. But it is more flexible because it follows the inline axis, whatever direction that happens to be.

writing-mode:
.panel {
  writing-mode: horizontal-tb;
}

.panel {
  inline-size: 220px;
  block-size: 140px;
}
*,
::before,
::after {
  box-sizing: border-box;
}

.panel {
  display: grid;
  place-items: center;
  border: 3px solid #111;
  border-radius: 0.75rem;
  background: #f2f2f2;
  font-family: system-ui, sans-serif;
  padding: 1rem;
}
inline-size + block-size

This is one of the clearest examples of logical thinking. The same CSS still makes sense even when the writing mode changes.

Logical positioning with inset

Positioned elements can also use logical properties.

  • inset-inline-start
  • inset-inline-end
  • inset-block-start
  • inset-block-end
  • inset-inline
  • inset-block

Logical inset properties only affect positioned elements, and their mapping depends on writing mode, direction, and text orientation.

direction:
.box {
  direction: ltr;
}

.badge {
  inset-inline-end: 0.75rem;
  inset-block-start: 0.75rem;
}
*,
::before,
::after {
  box-sizing: border-box;
}

.box {
  position: relative;
  inline-size: 260px;
  min-block-size: 160px;
  padding: 1rem;
  border: 3px solid #111;
  border-radius: 0.75rem;
  background: #f8f8f8;
  font-family: system-ui, sans-serif;
}

.badge {
  position: absolute;
  padding: 0.4rem 0.65rem;
  border-radius: 999px;
  background: #111;
  color: #fff;
  font-size: 0.9rem;
}
Pinned Positioned with logical inset values.

This gives you a badge pinned to the inline end and block start corner, instead of saying “top-right” forever.

Direction and writing mode

This is where logical properties become truly interesting.

The direction property

The direction property controls left-to-right versus right-to-left flow for text, table and grid columns, and horizontal overflow, though document direction is often better expressed with the HTML dir attribute.

For example:

  • direction: ltr;
  • direction: rtl;

The writing-mode property

The writing-mode property controls whether lines run horizontally or vertically and how blocks progress. When applied broadly, it is commonly set on the root element.

Common values include:

  • horizontal-tb
  • vertical-rl
  • vertical-lr

Simple mapping examples

In a common English page:

  • inline-start is usually left
  • inline-end is usually right
  • block-start is usually top
  • block-end is usually bottom

But in right-to-left text, inline start and inline end flip. In vertical writing, the mapping can shift much more dramatically. That is why the browser does the translation for you.

direction:
.demo {
  direction: ltr;
}

.demo {
  padding-inline-start: 2rem;
  border-inline-start: 10px solid rebeccapurple;
}
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  max-inline-size: 28rem;
  padding-inline-end: 1rem;
  padding-block: 1rem;
  border-block: 3px solid #111;
  border-inline-end: 3px solid #111;
  border-radius: 0.75rem;
  background: #f7f3ff;
  font-family: system-ui, sans-serif;
}
The highlighted side follows the start of the inline axis.

Logical properties cheat sheet

Here is a practical starter mapping list:

  • margin-leftmargin-inline-start in many LTR cases
  • margin-rightmargin-inline-end in many LTR cases
  • margin-topmargin-block-start
  • margin-bottommargin-block-end
  • padding-leftpadding-inline-start
  • padding-rightpadding-inline-end
  • border-topborder-block-start
  • border-bottomborder-block-end
  • widthinline-size
  • heightblock-size
  • left → often inset-inline-start
  • right → often inset-inline-end
  • top → often inset-block-start
  • bottom → often inset-block-end

I say “often” because the exact physical side depends on writing mode and direction.

Practical layout patterns

Card layouts

Cards are a wonderful place to use logical padding, logical width, and logical margins.

.card {
  max-inline-size: 24rem;
  padding-inline: 1.25rem;
  padding-block: 1rem;
}

.card h3 {
  margin-block: 0 0.5rem;
}

.card p {
  margin-block: 0;
}
*,
::before,
::after {
  box-sizing: border-box;
}

.card {
  border: 3px solid #111;
  border-radius: 1rem;
  background: #f7f7f7;
  font-family: system-ui, sans-serif;
}

.card h3 {
  font-size: 1.2rem;
}

.card p {
  line-height: 1.5;
}

Logical card

This card uses logical size, padding, and block margins.

Media object pattern

A classic thumbnail-and-text layout often needs space between image and content. Logical margins make that spacing adapt better.

.media {
  display: flex;
  align-items: start;
  gap: 1rem;
}

.media img {
  inline-size: 96px;
  block-size: 96px;
}

.media-content h3 {
  margin-block: 0 0.4rem;
}

.media-content p {
  margin-block: 0;
}
*,
::before,
::after {
  box-sizing: border-box;
}

.media {
  max-inline-size: 34rem;
  padding: 1rem;
  border: 3px solid #111;
  border-radius: 1rem;
  background: #fff;
  font-family: system-ui, sans-serif;
}

.media img {
  object-fit: cover;
  border-radius: 0.75rem;
  display: block;
}
Random placeholder

Media object

Logical sizes work well with components that may appear in different writing directions.

Migration tips

You do not need to rewrite your whole stylesheet in one dramatic weekend. A calmer approach is better.

  1. Start with margin, padding, and sizing
  2. Replace obvious left/right spacing rules with inline start/end rules
  3. Use inline-size and max-inline-size for component widths
  4. Use logical inset values for positioned UI details like badges and close buttons
  5. Test with dir="rtl" and at least one alternate writing mode

This gradual migration style is usually much easier than trying to transform everything at once.

Common mistakes

Mixing physical and logical properties without thinking

You can mix them, but do it carefully. If you declare both margin-left and margin-inline-start on the same element, make sure you understand which one should win and why.

Forgetting writing mode and direction

Logical properties make the most sense when you remember that they are based on flow. If nothing seems to change, it may be because your current writing mode and direction still map to the same physical side you expected.

Using inset on non-positioned elements

Logical inset properties, like physical top and left, do not affect normal non-positioned elements. Give the element position: relative, absolute, fixed, or sticky as needed.

Assuming inline always means horizontal

It often does in everyday English pages, but that is not a rule of the universe. In vertical writing modes, the inline axis is not horizontal.

Logical properties vs physical properties

Physical properties are not wrong. They are still perfectly valid and sometimes absolutely fine, especially for tightly controlled art direction or one-off effects.

But logical properties are usually a better choice when:

  • the component might be reused in different languages
  • the layout should be writing-mode-aware
  • you want your intent to be about content flow rather than screen side
  • you want more resilient components

A small conversion example

Here is the kind of upgrade you will often make in real projects:

.alert {
  padding-left: 1rem;
  border-left: 8px solid crimson;
  width: 320px;
}
.alert {
  padding-inline-start: 1rem;
  border-inline-start: 8px solid crimson;
  inline-size: 320px;
}
*,
::before,
::after {
  box-sizing: border-box;
}

.alert {
  padding-block: 1rem;
  padding-inline-end: 1rem;
  border-block: 3px solid #111;
  border-inline-end: 3px solid #111;
  border-radius: 0.75rem;
  font-family: system-ui, sans-serif;
  background: #fff1f3;
}
A logical version usually adapts better.

The first snippet works, but the second is more adaptable.

Final recap

CSS logical properties are one of those features that feel slightly abstract for ten minutes and then suddenly feel wonderfully obvious.

  • They describe layout relative to content flow
  • They use inline and block axes
  • They use start and end instead of fixed sides
  • They adapt better to different directions and writing modes
  • They are especially useful for spacing, borders, sizing, and positioned details

If you are just starting, begin with these four upgrades:

  1. margin-inline and padding-inline
  2. margin-block and padding-block
  3. inline-size and block-size
  4. border-inline-start and inset-inline-end

Master those, and you will already be writing CSS that is more robust, more reusable, and much less tied to a single reading direction.