必须在元素上设dir="rtl",否则表单光标、tab焦点流、flex主轴等关键行为无法翻转;局部设置或仅用css无效,需同步lang属性,并用处理混排文本,input等控件须单独设dir。

必须在 元素上显式设置 dir="rtl",否则表单光标、Tab 焦点流、Flex 主轴起点等关键行为不会真正翻转——只靠 CSS 或局部 dir 无法补救。
整页 RTL 必须从 开始设 dir
浏览器的 Unicode 双向算法(UBA)依赖根方向锚点启动。若仅在 或某个 <div> 上加 <code>dir="rtl",会导致:
-
<input>和<textarea></textarea>光标仍默认停在左侧,输入阿拉伯语时首字符跳到右边,体验断裂 - Tab 键焦点按 LTR 顺序移动(左→右),违反 RTL 用户直觉
-
flex-direction: row不自动将主轴起点移到右侧,justify-content: flex-start仍对齐左边缘 - 第三方 UI 库(如 Bootstrap、MUI)的方位类名(如
ms-2)无法自动映射为me-2,需额外 RTL 样式表
正确写法:。SSR 渲染时也必须由服务端输出该属性,避免 hydration 后方向不一致。
局部混排文本用 <bdi></bdi>,别用 dir="auto"
当内容来自 API(如用户名、评论、搜索关键词),方向不确定且可能含混合字符(如 "أحمد123"),dir="auto" 极易失效:
- 首字符是 ASCII 字母或数字(
"Hello"、"123")→ 强制 fallback 到ltr - 首字符是中文/日文/韩文(无强方向性)→ 同样 fallback 到
ltr - Safari 旧版和 Android WebView 对
dir="auto"支持不稳定,甚至完全忽略
应统一用:<bdi>{{username}}</bdi>。<bdi></bdi> 触发独立 Bidi 隔离上下文,不影响父级方向,也不强制反转数字顺序(对比 <bdo dir="rtl"></bdo> 会把 "123" 显示为 "321")。
<input> 和 <textarea></textarea> 必须单独设 dir
表单控件不会完全继承 的 dir 值,其内部光标行为、退格逻辑、粘贴顺序都依赖自身 dir 属性:
- 即使页面全局是 RTL,
<input type="text" dir="ltr">仍可正确输入英文 URL 或日期(如"example.com/2024") - 阿拉伯语输入框应明确写
<input dir="rtl">,否则光标初始位置错误,连续输入时方向抖动 - 不要试图用
style="direction: rtl"替代——它不改变getSelection().anchorOffset或剪贴板行为
动态场景下,可用 JS 设置:document.getElementById("nameInput").dir = "rtl";,但需确保 DOM 已挂载。
dir 和 CSS direction 不可互换
dir 是 HTML 语义层属性,影响底层逻辑;direction 是 CSS 布局层声明,仅控制渲染表现:
-
dir="rtl"→ 触发 UBA、翻转 Tab 流、修正<select></select>下拉项顺序、影响屏幕阅读器解析 -
style="direction: rtl"→ 仅调整行内盒对齐与换行,<input>光标仍从左起,复制文本到记事本后顺序错乱 - 两者共存时,
dir永远优先;但unicode-bidi: plaintext会彻底禁用 UBA,导致阿拉伯文字逐字左排,应避免
真正需要方向控制的地方,只写 dir,CSS 中用逻辑值替代物理值:text-align: start、margin-inline-start,这样在 dir 切换时能自动适配。
最容易被忽略的是:动态切换语言后,仅改 document.documentElement.dir 不够——某些浏览器不会重排已渲染的 <input> 光标位置,需手动触发 focus/blur 或重置 selection。











