CSS 逻辑属性将物理方向关键字(top、right、bottom、left)替换为适应书写模式和文本方向的逻辑等价物。不再使用 margin-left,而是使用 margin-inline-start——在从左到右和从右到左的布局中,它会自动变成正确的方向。这使构建真正国际化的用户界面变得简单得多。
物理 vs 逻辑:核心概念
物理属性与屏幕坐标绑定。逻辑属性相对于文档的书写模式和文本方向。
/* 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 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 */
}无需重复 CSS 的 RTL 支持
逻辑属性的杀手级用例:编写一套适用于从左到右(英语、法语)和从右到左(阿拉伯语、希伯来语)布局的 CSS,无需任何方向特定的覆盖。
/* 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! */
}边框和圆角
所有边框属性都有逻辑等价物,包括有些冗长的 border-radius 逻辑属性。
/* 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 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;
}完整属性映射参考
| 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 | - |
浏览器支持(2026年)
所有 CSS 逻辑属性在 2026 年都有完整的浏览器支持。基本属性(margin-block、margin-inline、padding-block、padding-inline)自 Chrome 87、Firefox 66 和 Safari 14.1 起就已支持。只有 border-radius 逻辑变体(border-start-start-radius 等)需要 Safari 15+ 才能完全支持。
常见问题
我应该将所有物理属性迁移到逻辑属性吗?
不一定。对于真正的物理属性(如 border-radius 或明确的宽度约束),物理属性是可以的。当属性与文本流方向相关时,逻辑属性才能发挥优势。优先考虑:flex/grid 项目上的 margin/padding、border-start/end 强调和文本容器上的 inline-size/block-size。
inline-size 和 width 有什么区别?
在水平书写模式(默认)中,inline-size 等同于 width。在垂直书写模式(writing-mode: vertical-rl)中,inline-size 映射到 height。使用 inline-size 为垂直书写模式支持提供前瞻性布局,无需重写 CSS。
我可以在 Tailwind CSS 中使用逻辑属性吗?
可以!Tailwind CSS v3.3+ 添加了逻辑属性实用类。使用 ms-* 表示 margin-inline-start(而不是 ml-*),me-* 表示 margin-inline-end,ps-* 表示 padding-inline-start,pe-* 表示 padding-inline-end。Tailwind 还为 text-start、float-start 等添加了 start/end 变体。
逻辑属性如何影响 flexbox 和 grid?
Flexbox 和 CSS Grid 已经使用逻辑术语:justify-content(内联轴)和 align-items(块级轴)。在使用逻辑属性的 flex/grid 时,一切都是一致的——margin-inline-end 在内联方向上为 flex 项目添加间距,无论书写模式如何。
混合使用物理和逻辑属性有什么陷阱吗?
有。如果在同一元素上同时设置 margin-left 和 margin-inline-start,行为取决于顺序。在相同特异性下,后者优先。这在迁移期间可能导致令人困惑的冲突。最佳实践:将组件的属性完全迁移到一个系统,而不是混合使用两者。