:dir(rtl)不是自动镜像开关,仅提供方向条件;必须显式设<html dir="rtl">、优先用逻辑属性(如margin-inline-start),仅在无逻辑等价物时(如transform: scaleX(-1))才用其兜底,且不可与[dir="rtl"]混用。
直接结论::dir(rtl)不是“开箱即用”的镜像开关,它只提供方向判断条件;真正适配 RTL,必须配合逻辑属性或手动覆盖物理属性——否则写了也白写。
常见现象是样式完全不触发,尤其在 SSR 页面或 Safari 旧版本里。根本原因不是语法错,而是浏览器根本没算出该元素的 direction 为 rtl。
dir="rtl" 必须出现在 <html> 标签上(不是 <body> 或局部 <div>),否则表单光标、选区、滚动条等底层行为不翻转,:dir(rtl) 也失去计算依据:dir(rtl)),必须显式设 dir="rtl" 才能匹配<html> 而没注入 dir 属性,CSS 解析阶段方向仍是 ltr,:dir(rtl) 规则压根不会进入匹配队列lang="ar" 对 :dir() 完全无效——别把它和方向混为一谈优先用逻辑属性,它们天然响应方向;:dir(rtl) 只在逻辑属性不可用时兜底。
margin-inline-start 替代 margin-left,padding-inline-end 替代 padding-right —— 这些无需 :dir() 就能自动翻转float: inline-start 或 inset-inline-start: 10px;若必须用物理值,才写两套:.sidebar:dir(ltr) { left: 0; } + .sidebar:dir(rtl) { right: 0; }
transform: scaleX(-1) 没有逻辑等价物,必须靠 .icon:dir(rtl) { transform: scaleX(-1); }
text-align: right 在 :dir(rtl) 里是多余的——direction: rtl 已让 text-align: start 自动对齐右端两者匹配机制完全不同,混在一起会让调试变成猜谜游戏。
立即学习“前端免费学习笔记(深入)”;
[dir="rtl"] 只匹配**显式写了该属性**的元素,不继承、不推断;p[dir="rtl"] 选不到 <body dir="rtl"><p> 里的 <p>
:dir(rtl) 匹配的是浏览器**最终计算出的方向值**,可继承、可由内容推断(如阿拉伯字符)[dir="rtl"] .btn 和 .btn:dir(rtl),CSS 优先级相同,谁在后面谁覆盖,但你根本没法预测哪些元素实际命中哪条规则dir="rtl" 后,它自己的 [dir="rtl"] 规则可能和你的 :dir(rtl) 冲突最易被忽略的点:RTL 不是纯视觉翻转,它牵扯到 Unicode 双向算法(UBA)、屏幕阅读器语音规则、输入法光标行为——:dir(rtl) 只管样式层,dir="rtl" 才是启动整套 RTL 机制的钥匙。漏掉根节点的 dir,其他全是空中楼阁。