CSS 逻辑属性和书写模式是什么?为什么要用 block 与 inline?
简化版
物理属性用 top、right、bottom、left 绑定屏幕方向,逻辑属性用 block 与 inline 描述文字排版方向。margin-inline-start、padding-block、inline-size 等会随 writing-mode 和 direction 自动映射,适合国际化和可复用组件,但背景位置、变换等能力仍可能需要物理方向。
详细版
块轴是段落依次排列的方向,行内轴是文字在一行中推进的方向。默认横排从左到右时,inline-start 是左、block-start 是上;阿拉伯语横排时 inline-start 变成右;竖排时块轴和行内轴还会旋转。
常见映射包括 width → inline-size、height → block-size、margin-left/right → margin-inline-start/end、border-top → border-block-start。成对简写如 margin-inline 可同时设置行内起止两端。
迁移时应从组件语义出发,检查 Flex/Grid 轴、图标方向、滚动和动画,不能只做字符串替换。
完整版教学
一、物理方向为什么限制组件复用
一个提示卡写 border-left: 4px solid,在中文和英文界面里可以表示“起始侧强调”。切换到从右向左的阿拉伯语后,内容起点在右边,边框留在左边就不再符合阅读方向。
.notice {
border-inline-start: 4px solid #2563eb;
padding-inline-start: 16px;
}
逻辑属性描述“阅读起点一侧”,浏览器再结合书写模式映射到实际边。组件无需为 LTR、RTL 和竖排各复制一套基础间距规则。
二、block 与 inline 是两条排版轴
inline 轴表示一行中文字推进的方向,block 轴表示一行行或一段段堆叠的方向。在常见 horizontal-tb; direction: ltr 中,inline 从左到右,block 从上到下。
horizontal-tb + ltr
inline-start ─────────→ inline-end
block-start
│
↓
block-end
direction: rtl 主要反转横排的 inline 方向,而 writing-mode: vertical-rl 会让文字从上到下推进、列从右向左排列。只记“inline 等于水平”在竖排模式中会出错。
三、尺寸和边距都有逻辑对应物
inline-size 是行内轴尺寸,默认横排中等于宽度;block-size 是块轴尺寸,默认等于高度。起止边可以组合出 margin、padding、border 和 inset 等属性。
| 物理属性 | 默认横排逻辑属性 | 表达含义 |
|---|---|---|
width | inline-size | 行内轴尺寸 |
height | block-size | 块轴尺寸 |
margin-left | margin-inline-start | 阅读起点外边距 |
padding-top | padding-block-start | 块轴起点内边距 |
right: 0 | inset-inline-end: 0 | 行内末端定位 |
margin-inline: auto 在默认横排下等价于左右自动外边距,可用于居中;在竖排时则沿文字推进轴工作。逻辑简写使意图比四边物理值更直接。
四、方向切换能消除大量覆盖规则
传统 RTL 适配常先写 margin-left: 12px,再用 [dir="rtl"] 覆盖为 margin-left: 0; margin-right: 12px。每个组件多两条声明,100 个组件可能增加约 200 条方向覆盖。
/* 物理写法 */
.icon { margin-right: 12px; }
[dir="rtl"] .icon { margin-right: 0; margin-left: 12px; }
/* 逻辑写法 */
.icon { margin-inline-end: 12px; }
逻辑属性把映射交给浏览器,减少遗漏和后续维护。但箭头图标表达“前进”时仍可能要根据方向镜像,因为图形语义不是 margin 能自动解决的。
五、Flex 与 Grid 轴不能和逻辑轴混为一谈
Flex 的主轴由 flex-direction 决定,row 通常沿 inline 轴,column 通常沿 block 轴,但 row-reverse、书写模式和方向会改变具体起点。Grid 的行列也受书写模式映射,不能永远把 column 理解成屏幕水平。
.toolbar {
display: flex;
gap: 12px;
padding-inline: 16px;
min-block-size: 44px;
}
这里 min-block-size: 44px 表达工具栏在块轴至少 44px,比直接写 height 更贴近排版意图。调试国际化布局时,应查看实际 writing mode,而不是只看屏幕坐标。
六、渐进迁移要区分结构方向和视觉方向
边距、内边距、边框、尺寸和绝对定位通常很适合逻辑属性。阴影偏移、CSS transform、背景图片焦点和地图坐标等具有真实物理方向,强行逻辑化反而会改变设计含义。
| 场景 | 是否优先逻辑属性 | 理由 |
|---|---|---|
| 文本前方图标间距 | 是 | 应随阅读方向变化 |
| 卡片顶部阴影 | 否/视设计 | 光源可能是物理方向 |
| 抽屉从阅读末端出现 | 是 | 可用 inset-inline-end |
| 指南针向北箭头 | 否 | 方向与语言无关 |
迁移可先从设计令牌和公共组件开始,在 dir="rtl" 与竖排测试页中验证。浏览器支持目标也应由项目兼容矩阵决定,不要凭记忆判断。
记忆钩子:物理属性回答“屏幕哪一边”,逻辑属性回答“文字排版的哪一端”;先问设计意图属于哪一种。
七、常见误区与追问
- 误区:
inline永远代表水平方向。 竖排书写模式中 inline 轴可能从上到下。 - 误区:设置
direction: rtl就完成了全部 RTL 适配。 图标、动画、数据图表和混合方向文本仍需逐项检查。 - 误区:逻辑属性可以替代所有 top/right/bottom/left。 有真实物理语义的效果仍应使用物理方向。
- 追问:
margin-inline: auto有什么作用? 它让行内轴两端自动分配剩余空间,默认横排中常用于水平居中。 - 追问:
start与end由什么共同决定? 由writing-mode、direction以及具体轴共同映射。 - 追问:为什么混合写法危险? 同一元素同时声明物理和逻辑边时,最终结果还取决于层叠顺序,方向切换后更难预测。
八、加强记忆
建立两套坐标系就容易判断:屏幕坐标是上下左右,排版坐标是 block/inline 与 start/end。组件间距、尺寸和边框若服务于阅读流,应优先写逻辑属性,让中文横排、RTL 横排和竖排自动映射;阴影光源、地图方位等真实空间效果则保留物理属性。迁移时成组替换并测试方向,不混用互相竞争的声明,就能让国际化从大量覆盖规则变成布局系统的自然能力。