必须在上设dir="rtl"并同步设置lang,否则光标、选区、滚动条等rtl行为错乱;是嵌入ltr内容的唯一可靠方式;:dir(rtl)伪类更准确但需浏览器支持;物理css属性需用逻辑属性或兼容写法手动翻转。

必须在 上设 dir="rtl",否则光标、选区、滚动条全错乱
只给 或某个 <div> 加 <code>dir="rtl",浏览器不会真正启用 RTL 感知机制。旧版 Safari 和部分 Chromium 版本中,<input> 光标跳转反向、双击选词顺序颠倒、复制粘贴内容乱序、<select></select> 下拉方向不翻转、滚动条仍卡在右侧——这些都不是样式问题,而是底层文本流未被识别。
正确做法只有这一种:(lang 必须同步设置,否则字体连字、数字渲染、屏幕阅读器语音规则全失效)。动态切换时,JavaScript 必须成对修改:document.documentElement.setAttribute("dir", "rtl") 和 document.documentElement.setAttribute("lang", "ar")。
<bdi></bdi> 是嵌入 LTR 内容的唯一可靠方式,direction: ltr 无效
阿拉伯语段落里放 URL、版本号(如 v2.4.1)、英文品牌名,纯靠 dir="rtl" 会显示成 1.4.2 v API 或括号开口反向——这不是 bug,是 Unicode 双向算法(UBA)没收到明确锚点。
-
<bdi></bdi>是 HTML5 原生元素,专为隔离双向文本设计,它自动插入 RLM/LRM 控制符,参与 UBA,复制出来也是可读顺序 - 不要用
span style="direction: ltr"替代,它不触发 UBA,复制粘贴照样乱 - 避免在
<input>或<textarea></textarea>上漏掉dir="auto"或dir="rtl",否则用户输入阿拉伯语时退格键行为异常
:dir(rtl) 伪类比 [dir="rtl"] 更靠谱,但有兼容性陷阱
[dir="rtl"] 只匹配显式写了属性的元素,无法捕获继承方向的子节点,更抓不到系统语言自动推断出的 RTL 场景。而 :dir(rtl) 看的是实际文本流方向,不管这个方向来自 还是浏览器自动判断。
Chrome 91+、Safari 17+、Firefox 已支持,但需注意:
- Chrome 需开启
chrome://flags/#enable-experimental-web-platform-features - Safari 要在「开发 → 实验性功能」中勾选
:dir()伪类 -
:dir(rtl)不响应纯 CSS 的direction: rtl,必须由 HTMLdir属性或浏览器推断触发 - 不能嵌套写
div:dir(rtl) span:dir(ltr),子元素显式设dir="ltr"后,它自己会匹配:dir(ltr),父选择器不穿透
物理 CSS 属性不会随 dir="rtl" 自动翻转,必须手动处理
dir="rtl" 会改变文本基线、Flex 主轴起始、Tab 焦点流、text-align: start 含义,但以下属性完全不受影响:
-
margin-left/padding-right→ 改用margin-inline-start/padding-inline-end -
float: left→ 改用float: inline-start,或降级写:dir(rtl) { float: right; } -
left: 10px→ 改用inset-inline-start: 10px,或兼容写法:dir(rtl) { right: 10px; } -
background-position: left top→ 改用background-position: inline-start top - 别用
flex-direction: row-reverse模拟 RTL——它会翻转所有子项顺序,交互逻辑可能崩坏
最易忽略的点:表单控件的视觉翻转(如日期选择器箭头、复选框位置)不依赖 dir,必须单独适配;number 输入框也不该加 dir,数字本身是强 LTR,加了反而干扰输入逻辑。











