dir="rtl"必须设在上,因浏览器仅在此层级完整触发表单光标、选中顺序及滚动条rtl行为;局部设置会导致旧版safari等光标错乱、复制乱序,且需同步lang="ar"以启用连字、数字样式与语音规则。

dir="rtl" 必须加在 根元素上,不能只加在表单容器里
很多开发者试过给 <form></form> 或某个 <div class="form"> 加 <code>dir="rtl",结果发现输入框光标乱跳、数字显示错位、下拉箭头方向没变——这是因为浏览器对表单控件(如 <input>、<select></select>)的 RTL 感知只响应根级 dir 属性。旧版 Safari 尤其明显:局部 dir 会导致 <input type="text"> 的选中行为异常。
正确做法只有这一种:
-
(必须同时带lang,语义和渲染缺一不可) - 避免在
<form></form>上重复写dir="rtl",纯属冗余,还可能干扰 CSS 选择器优先级 - 若需动态切换语言,用 JavaScript 修改
document.documentElement.dir,而不是操作表单节点
阿拉伯语混合数字时,<bdi></bdi> 是绕不开的包裹标签
阿拉伯语句子中夹着英文或数字(比如 “الإصدار v2.4.1” 或 “مدة الصلاحية: 30 يوماً”),不处理就会被强制镜像:30 → “03”,v2.4.1 → “1.4.2v”。这不是字体问题,是 Unicode 双向算法(Bidi Algorithm)自动推导方向导致的。
解决方式不是改 CSS,而是用语义化 HTML 修正内容方向:
- 所有含数字/拉丁字母的文本节点,用
<bdi></bdi>包一层:<label>الإصدار <bdi>v2.4.1</bdi></label> - 表单 placeholder 也得包裹:
<input placeholder="أدخل <bdi>iOS 18</bdi>"> - 不用
dir="ltr"替代<bdi></bdi>—— 后者会自动检测首字符方向,更鲁棒;前者需要你手动判断并硬编码
Milligram / Bootstrap-Sass 等框架的 RTL 表单要重写左右类名逻辑
原生 Milligram 没有 RTL 支持,.float-left 在 RTL 下仍向左浮动,结果整个表单结构翻车。Bootstrap-Sass 虽有变量机制,但默认不启用 RTL 分支,必须手动干预。
关键修改点集中在三处:
- 网格与列顺序:
[dir="rtl"] .row { flex-direction: row-reverse; },否则<div class="column"> 排列顺序还是 LTR <li>表单控件间距:<code>[dir="rtl"] .form-group { margin-inline-start: 0; margin-inline-end: 1rem; },用逻辑属性替代margin-left/margin-right - 按钮组顺序:
[dir="rtl"] .btn-group > .btn { margin-inline-start: 0.25rem; },否则 “إلغاء” 和 “إرسال” 按钮左右颠倒
注意:不要直接覆盖框架源码里的 float: left 为 float: right —— 这样会让 LTR 页面失效。必须用 [dir="rtl"] 选择器做条件切换。
Adaptive Cards 或 JSON Schema 表单需显式声明 rtl: true
如果你用的是 Microsoft Adaptive Cards、Form.io 或其他基于 JSON Schema 的表单引擎,HTML 层面的 dir="rtl" 不生效。这类系统有自己的方向控制字段。
例如 Adaptive Cards 的 JSON 必须包含顶层 rtl: true:
{"type": "AdaptiveCard", "version": "1.5", "rtl": true, "body": [...]}
漏掉这行,即使 HTML 根元素设了 dir="rtl",卡片内的 <input.text></input.text>、<input.choiceset></input.choiceset> 依然按 LTR 渲染。同理,Form.io 的 schema 中要加 "direction": "rtl" 字段。
容易忽略的一点:这些 JSON 配置里的文本(如 "text": "اسم المستخدم")本身不需要额外包裹 <bdi></bdi> —— 渲染层会自动处理,但 placeholder、hint 等动态文本仍需前端 JS 做 bdi 插入。
RTL 表单最麻烦的从来不是样式翻转,而是数字、嵌入英文、第三方组件(比如日期选择器、富文本编辑器)的方向感知缺失。别指望一个 dir="rtl" 解决全部问题,该用 <bdi></bdi> 就用,该改框架变量就改,该补 JSON 字段就补——混合内容才是真实场景的常态。











