必须使用 dir 属性而非 direction css 属性,因 unicode 双向算法仅响应 dir;错误使用 direction 会导致光标、焦点、复制粘贴、读屏等语义行为异常;关键场景须显式声明 dir="ltr"/"rtl",动态切换需修改 document.documentelement.dir 并持久化。

必须用 dir 属性,而不是 direction CSS 属性
浏览器对文本方向的底层处理依赖 Unicode 双向算法(Bidi Algorithm),而该算法只响应 HTML 的 dir 属性,不响应 direction。只写 style="direction: rtl" 会导致光标乱跳、Tab 焦点顺序反向、复制粘贴后数字顺序错乱、屏幕阅读器读错顺序——这些都不是样式问题,是语义缺失。
常见错误现象包括:
- 阿拉伯语输入框中光标总停在最右边,无法从左开始输入
- 英文单词混在阿拉伯语中时括号翻转,比如
(مرحبا)渲染成)مرحبا( - 表单按 Tab 键时焦点从右往左跳,违背用户预期
正确做法是:全局方向必须设在 上;局部切换用 dir 属性包裹元素,而非仅靠 CSS。
dir="auto" 在多数场景下不可靠
dir="auto" 表面省事,实则限制极多。它只看首字符的 Unicode 类别,且一旦判定就不再更新,动态插入内容完全不触发重判。
典型失效场景:
- 中文开头(如“你好,نص عربي”)→ 默认 fallback 为
ltr,阿拉伯语部分被当作 LTR 处理 - 首字符是 ASCII 字母、数字或空格 → 直接定为
ltr,哪怕后续全是希伯来字母 - JS 执行
el.innerHTML = "שלום"后,即使el.dir = "auto",也不会重新推断方向 - Safari 对某些组合字符(如带变音符号的阿拉伯字母)判断不稳定
结论:关键文案、表单、多语言混合区域,一律避免 dir="auto";应显式声明 dir="rtl" 或 dir="ltr"。
动态切换方向必须操作 document.documentElement.dir
JavaScript 切换页面方向时,改 document.body.dir 或某个 <div> 的 <code>dir 属性是无效的。只有修改 document.documentElement(即 元素)才能触发全链路重排:光标位置、Tab 流、Flex 主轴、<textarea></textarea> 默认起始点、甚至滚动条位置都会同步更新。
实操要点:
- 正确写法:
document.documentElement.dir = 'rtl' - 错误写法:
document.body.setAttribute('dir', 'rtl')→ 表单光标和焦点流仍按旧方向运行 - 若需持久化,切换后应存入
localStorage,并在页面加载时读取并赋值,否则刷新即回退 - 不要在
DOMContentLoaded之前读取/设置,否则可能被后续框架覆盖
局部多语言混排必须用 dir 显式隔离,不是靠 unicode-bidi
当阿拉伯语段落里嵌一段英文产品名(如 “iPhone 15”),或希伯来语页面中显示邮箱地址,不能指望 unicode-bidi: embed 或 bidi-override 来“修”方向——它们只是双向算法的微调工具,不改变继承链和语义起点。
真正有效且语义正确的做法是:
- 用
<span dir="ltr">iPhone 15</span>包裹 LTR 内容,确保其子树独立应用 Bidi 算法 - 避免在
<table> 上只加 <code>style="direction: rtl",会导致列顺序混乱;应改为<table dir="rtl"> <li> <code><bdi></bdi>适合包裹不可信的外部输入(如用户昵称),但它不重置布局流向或焦点顺序,不能替代dir - 不要在已设
dir="rtl"的容器内,再对子元素写style="direction: ltr"——CSSdirection不会覆盖父级dir的语义继承
最容易被忽略的是:只要没动 document.documentElement.dir,哪怕所有文字都“看起来”右对齐了,底层交互逻辑仍是错的。











