必须在<html>元素上设dir="rtl",否则整页RTL布局必然出错——光标乱跳、Tab顺序反、<input>退格方向错、滚动条还在右边,这些都不是CSS能修好的。

必须在 <html> 元素上设 dir="rtl",否则整页 RTL 布局必然出错——光标乱跳、Tab 顺序反、<input> 退格方向错、滚动条还在右边,这些都不是 CSS 能修好的。
为什么不能只加 direction: rtl 或 <body dir="rtl">
浏览器只在根元素 <html> 上识别 dir 属性,才启动完整的 Unicode 双向算法(UBA):光标逻辑、表单控件翻转、<select> 下拉箭头、Flex 主轴起点都会随之适配。仅用 CSS direction: rtl 只改文本流和部分盒模型,<textarea> 光标仍从左开始跳,<input type="search"> 的清除按钮还在右边。而 <body dir="rtl"> 不合法,也不生效——HTML 规范明确要求方向基线由 <html> 定义。
<html> 上怎么写才对
直接在 <html> 标签里加 dir="rtl" 和同步的 lang 属性:
<html dir="rtl" lang="ar">
注意以下几点:
立即学习“前端免费学习笔记(深入)”;
-
lang必须同步设置,否则字体连字、数字样式、屏幕阅读器语音规则均不生效 - 不要写成
<html dir="rtl" lang="en">这类矛盾组合 - 动态切换时,JavaScript 必须成对修改:
document.documentElement.setAttribute("dir", "rtl")和document.documentElement.setAttribute("lang", "ar") - 验证是否生效:检查 DOM 中
document.documentElement.dir值,别只看getComputedStyle(document.documentElement).direction
局部混排内容怎么处理
纯 dir="rtl" 无法保证阿拉伯语段落里的 URL、版本号(如 v2.4.1)、英文品牌名保持可读顺序。现象是 API v2.4.1 显示为 1.4.2 v API,括号也翻转。
根本原因是 UBA 需要显式隔离:
- 对不确定方向的内联内容(如用户昵称、API 返回字段),用
<bdi>包裹:<bdi>v2.4.1</bdi> - 避免用
unicode-bidi: isolate替代<bdi>——它不参与 UBA,复制出来仍是乱序 - 表格单元格单独 RTL,必须加在
<td>或<th>上:<td dir="rtl">مرحبا</td>,不能只加在<table>或<tr>上 - 含
<input>的单元格,<td>和<input>都得显式设dir="rtl",否则输入框内光标仍按文档默认方向走
容易被忽略的兼容性坑
真正难的不是加 dir,而是判断哪一层该加、哪一层该隔离、哪一层该用 CSS 替代。旧版 Safari(v17.4 之前)对 :dir() 伪类支持不全,<html dir="rtl"> 会破坏第三方 UI 库(如 Bootstrap 表单、React 组件)的样式逻辑——它们默认按 LTR 写 margin-left,一翻转图标就跑到文字右边甚至溢出。更稳妥的做法是:只在真正需要 RTL 的区域(如多语言切换后的内容区)加 dir="rtl",用 CSS 自定义属性控制对齐,保留布局结构不变;若必须全局切换,得同步注入 RTL 专用样式表,重置所有方位相关属性。



















