dir="rtl"自动翻转text-align:start/end含义、flex/grid主轴起始点、表单控件图标位置及滚动条默认位置;但margin-left等物理属性不翻转,须改用逻辑属性或[dir="rtl"]重写。

dir="rtl" 加到 是必要起点,但仅靠它远不够——它不翻转 margin-left、float: left、background-position: left 这类物理属性,布局错位是常态,不是例外。
哪些 CSS 属性会被 dir="rtl" 自动翻转?
浏览器底层响应的是「书写模式」,不是样式重绘。真正自动生效的只有:
-
text-align: start→ 在 RTL 下等价于text-align: right,end同理 - Flex/Grid 主轴起始点:
justify-content: flex-start在 RTL 下指向容器右侧 - 表单控件内置图标位置:
<select></select>箭头、<input type="search">清除按钮自动右置 - 滚动条默认出现在右侧(仅当
dir="rtl"作用于根元素时)
这些无需额外 CSS,但前提是 dir 必须设在语义正确的层级( 或局部 <div dir="rtl">),不能只靠 <code>direction: rtl。
margin-inline 和 padding-inline 为什么有时像没生效?
常见误用是写成 margin-inline: 10px —— 这是无效声明,浏览器直接忽略。正确写法必须是两个值:margin-inline: 10px 20px,分别对应 margin-inline-start 和 margin-inline-end。
更隐蔽的问题是:父元素没显式设 direction 或 writing-mode,浏览器按默认 ltr 解析,此时 margin-inline-start 就等于 margin-left,看起来“没变”,其实是对的。
验证是否生效,别只看 CSS 声明行,要查 computed style 中 margin-inline-start 和 margin-inline-end 的实际计算值。
Safari ≤15.3 对 margin-inline: 10px 20px 静默不支持,得拆成两行:margin-inline-start: 10px; margin-inline-end: 20px;
如何安全地兼容老浏览器并避免逻辑属性降级?
在 contenteditable 容器中,必须显式设 style="direction: ltr;"(哪怕值是默认),否则逻辑属性可能退化为物理映射,导致光标跳位或选区异常。
更稳妥的工程化做法是用 CSS 变量兜底:
:root { --side-start: left; --side-end: right; }
[dir="rtl"] { --side-start: right; --side-end: left; }
.box {
margin-<code>var(--side-start)</code>: 16px;
padding-<code>var(--side-end)</code>: 8px;
}
这样既保持语义清晰,又绕过 Safari 旧版对逻辑属性的支持缺陷,也方便后续迁移到纯逻辑属性。
最后注意:lang 属性必须显式写在每个含文本的语义标签上(<p lang="ar"></p>),不能只靠 继承——屏幕阅读器和字体回退链都依赖这个显式声明,漏掉就会导致标点宽度错、连字失效、阿拉伯数字分组混乱。











