CSS Logical Properties replace physical directional keywords (top, right, bottom, left) with logical equivalents that adapt to the writing mode and text direction. Instead of margin-left, you write margin-inline-start — and it automatically becomes the correct side in both left-to-right and right-to-left layouts. This makes building truly internationalized UIs dramatically simpler.
Physical vs Logical: The Core Concept
Physical properties are tied to the screen coordinates. Logical properties are relative to the document's writing mode and text direction.
/* CSS Logical Properties vs Physical Properties */
/* PHYSICAL (old way) — tied to top/right/bottom/left */
.box {
margin-top: 1rem;
margin-right: 2rem;
margin-bottom: 1rem;
margin-left: 2rem;
padding-left: 1.5rem;
padding-right: 1.5rem;
border-left: 2px solid blue;
width: 300px;
height: 200px;
}
/* LOGICAL (new way) — relative to writing direction */
.box {
margin-block: 1rem; /* top + bottom → block start + end */
margin-inline: 2rem; /* left + right → inline start + end */
padding-inline: 1.5rem; /* horizontal padding in any direction */
border-inline-start: 2px solid blue; /* 'left' in LTR, 'right' in RTL */
inline-size: 300px; /* width in horizontal writing */
block-size: 200px; /* height in horizontal writing */
}Understanding Inline and Block Axes
Logical properties use two axes: inline (the direction text flows) and block (the direction blocks are stacked). In English, inline is horizontal and block is vertical. In vertical Japanese text, they swap.
/* Understanding inline vs block axes */
/*
Horizontal writing mode (default English):
- inline axis → left ←→ right (text flows horizontally)
- block axis → top ↕ bottom (blocks stack vertically)
Vertical writing mode (Japanese, for example):
- inline axis → top ↕ bottom (text flows vertically)
- block axis → left ←→ right (blocks stack horizontally)
*/
/* Logical shorthand properties */
.element {
/* block = top/bottom, inline = left/right */
margin-block: 1rem 2rem; /* block-start: 1rem, block-end: 2rem */
margin-inline: auto; /* center horizontally (in LTR or RTL!) */
padding-block-start: 0.5rem; /* padding-top in LTR */
padding-block-end: 0.5rem; /* padding-bottom in LTR */
padding-inline-start: 1rem; /* padding-left in LTR, padding-right in RTL */
padding-inline-end: 1rem; /* padding-right in LTR, padding-left in RTL */
/* Size */
inline-size: 100%; /* width in horizontal writing */
min-inline-size: 200px; /* min-width */
max-inline-size: 800px; /* max-width */
block-size: auto; /* height */
/* Position (for position: absolute) */
inset-block-start: 0; /* top */
inset-inline-start: 0; /* left */
inset: 0; /* all four sides */
}RTL Support Without Duplicate CSS
The killer use case for logical properties: writing one set of CSS that works for both LTR (English, French) and RTL (Arabic, Hebrew) without any direction-specific overrides.
/* RTL support without duplicate CSS */
/* OLD WAY: separate RTL stylesheet */
/* main.css */
.sidebar {
margin-left: 0;
margin-right: 280px;
padding-left: 1rem;
border-right: 1px solid #ccc;
}
/* rtl.css (or [dir="rtl"] overrides) */
[dir="rtl"] .sidebar {
margin-left: 280px; /* override */
margin-right: 0;
padding-left: 0;
padding-right: 1rem;
border-right: none;
border-left: 1px solid #ccc;
}
/* --------------------------------------- */
/* NEW WAY: logical properties handle it automatically */
.sidebar {
/* No [dir="rtl"] override needed! */
margin-inline-start: 0;
margin-inline-end: 280px; /* gap before main content */
padding-inline-start: 1rem;
border-inline-end: 1px solid #ccc;
/* In RTL: margin-inline-start becomes right side automatically */
}
/* Example: icon + label that works in any direction */
.icon-label {
display: flex;
align-items: center;
gap: 0.5rem;
}
.icon-label .icon {
margin-inline-end: 0.5rem; /* space between icon and label */
/* In LTR: margin-right: 0.5rem */
/* In RTL: margin-left: 0.5rem — automatic! */
}Borders and Border Radius
All border properties have logical equivalents, including the somewhat verbose border-radius logical properties.
/* Borders with logical properties */
/* Physical */
.card {
border-top: 2px solid blue;
border-bottom: 1px solid gray;
border-left: 4px solid red; /* accent border */
border-right: none;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
/* Logical */
.card {
border-block-start: 2px solid blue; /* top */
border-block-end: 1px solid gray; /* bottom */
border-inline-start: 4px solid red; /* left in LTR, right in RTL */
border-inline-end: none;
border-start-start-radius: 8px; /* top-left in LTR */
border-start-end-radius: 8px; /* top-right in LTR */
}
/* Shorthand */
.card {
border-block: 1px solid #eee; /* top AND bottom */
border-inline: 2px solid #ccc; /* left AND right */
}Migration Guide
How to systematically convert an existing codebase from physical to logical properties.
/* Migration strategy: replace physical with logical */
/* Step 1: Search & Replace mapping */
/*
margin-top → margin-block-start
margin-bottom → margin-block-end
margin-left → margin-inline-start
margin-right → margin-inline-end
margin: T R B L → margin-block: T B; margin-inline: L R;
padding-top → padding-block-start
padding-bottom → padding-block-end
padding-left → padding-inline-start
padding-right → padding-inline-end
width → inline-size
height → block-size
min-width → min-inline-size
max-width → max-inline-size
min-height → min-block-size
max-height → max-block-size
top → inset-block-start
bottom → inset-block-end
left → inset-inline-start
right → inset-inline-end
*/
/* Step 2: Enable writing mode for testing */
.test-rtl {
direction: rtl; /* test RTL layout without changing HTML */
}
.test-vertical {
writing-mode: vertical-rl; /* test vertical layout */
}
/* Step 3: Keep physical for TRULY physical things */
.avatar {
/* These should stay physical — they don't relate to text direction */
border-radius: 50%; /* always round */
width: 48px; /* OR inline-size: 48px for consistency */
height: 48px;
}Complete Property Mapping Reference
| Physical Property | Logical Equivalent | Shorthand |
|---|---|---|
| margin-top | margin-block-start | margin-block (first value) |
| margin-bottom | margin-block-end | margin-block (second value) |
| margin-left | margin-inline-start | margin-inline (first value) |
| margin-right | margin-inline-end | margin-inline (second value) |
| padding-top | padding-block-start | padding-block |
| padding-bottom | padding-block-end | padding-block |
| padding-left | padding-inline-start | padding-inline |
| padding-right | padding-inline-end | padding-inline |
| width | inline-size | - |
| height | block-size | - |
| min-width | min-inline-size | - |
| max-width | max-inline-size | - |
| top | inset-block-start | inset |
| bottom | inset-block-end | inset |
| left | inset-inline-start | inset |
| right | inset-inline-end | inset |
| border-top | border-block-start | border-block |
| border-left | border-inline-start | border-inline |
| border-top-left-radius | border-start-start-radius | - |
| border-top-right-radius | border-start-end-radius | - |
| text-align: left | text-align: start | - |
| float: left | float: inline-start | - |
| resize: vertical | resize: block | - |
Browser Support (2026)
All CSS Logical Properties have full browser support in 2026. The basic properties (margin-block, margin-inline, padding-block, padding-inline) have been supported since Chrome 87, Firefox 66, and Safari 14.1. Only the border-radius logical variants (border-start-start-radius, etc.) required Safari 15+ for full support.
Frequently Asked Questions
Should I migrate all physical properties to logical properties?
Not necessarily. For properties that are truly physical (like border-radius, or explicit width constraints), physical properties are fine. Logical properties shine when the property relates to text flow direction. Prioritize: margin/padding on flex/grid items, border-start/end accents, and inline-size/block-size on text containers.
What is the difference between inline-size and width?
In horizontal writing mode (the default), inline-size is equivalent to width. In vertical writing mode (writing-mode: vertical-rl), inline-size maps to height. Using inline-size future-proofs your layout for vertical writing mode support without rewriting CSS.
Can I use logical properties in Tailwind CSS?
Yes! Tailwind CSS v3.3+ added logical property utilities. Use ms-* for margin-inline-start (instead of ml-*), me-* for margin-inline-end, ps-* for padding-inline-start, pe-* for padding-inline-end. Tailwind also added start/end variants for things like text-start, float-start, etc.
How do logical properties affect flexbox and grid?
Flexbox and CSS Grid already use logical terms: justify-content (inline axis) and align-items (block axis). When using flex/grid with logical properties, everything is consistent — margin-inline-end adds space after a flex item in the inline direction, regardless of writing mode.
Are there any gotchas when mixing physical and logical properties?
Yes. If you set both margin-left and margin-inline-start on the same element, the behavior depends on order. The last one wins in the same specificity. This can cause confusing conflicts during migration. Best practice: fully migrate a component's properties to one system rather than mixing both.