-
Notifications
You must be signed in to change notification settings - Fork 25
Description
双向性
从右向左(RTL)阅读的语言,例如阿拉伯语和希伯来语,其 UI 应该被镜像,以确保内容易于理解。
推荐方案
// direction 只能改变 display: flex/inline-block 元素的书写方,对于 float/绝对定位布局就无能为力,更别谈复杂的页面布局,比如[BFC 布局](https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context) 、[双飞翼、圣杯布局](https://juejin.im/post/5a9813d6f265da237506506f),input、textarea、img(图片的展示方向不会变)
html.rtl {
direction: rtl;
}
html.rtl input,textarea {
text-align: right;
}
// 针对图片、绝对定位
.icon-rtl {
transform: scaleX(-1),
}
// direction 无法改变 margin, padding, border 的水平方向,特殊场景特殊处理
RTL 布局概述
如上图所示,左右两边分别展示了 RTL 和 LTR 的效果图。从图中我们可以直观地看出两者布局的区别:文本的对齐方向、主按钮和辅助按钮的排列方向、进度条的填充方向以及返回图标的方向是相反的,而其他图标则是相同的。具体总结如下:
| LTR | RTL | |
|---|---|---|
| 文本 | 句子从左向右阅读 | 句子从右向左阅读 |
| 时间线 | 事件序列从左向右进行 | 事件序列从右向左进行 |
| 图像 | 从左向右的箭头表示向前运动:→ | 从右向左的箭头表示向前运动:← |
了解了 RTL 布局的特点之后,我们可以开始考虑如何低成本地将线上已有场景的 UI 从 LTR 调整为 RTL。在将 UI 从 LTR 调整为 RTL(或反之)时,我们通常称之为镜像。
实现 RTL 的两种方案
transfrom
基于 transform 的方案,是利用 CSS 的 transform 属性,通过设置 transform: scaleX(-1); 实现页面的水平翻转。
如上图所示,通过翻转解决了布局问题,但文字和图像也被翻转。为了解决这个问题,对于不需要翻转的内容(如文字、非指向性图像),需要进行二次翻转。然而,该方案的缺点在于,首次翻转只需要处理根节点,而二次翻转则需要处理所有不需要翻转的元素,工作量较大。该方案的优点在于开发者无需修改 JS 逻辑。例如,通常情况下,左滑/左向箭头图标的点击事件在 RTL 时会将前进改为后退,右向将后退改为前进。
direction
基于 direction 的方案,是利用 CSS 的 direction 属性,该属性用于设置文本、表格列和水平溢出的方向。通过将 direction 设置为 rtl 可以改变页面布局,在 html 标签上添加 dir="rtl" 与设置 direction 效果相同。我们通过一个简单的例子来具体了解设置为 rtl 的效果。
如上图所示,设置为 rtl 之后,我们发现 UI 并没有完全兼容 RTL 场景。我们可以观察到,direction 在设置 rtl 之后只对部分属性进行了镜像处理:
-
如果元素没有预先定义过
text-align,那么该元素的文本会从向左对齐变成向右对齐,如果设置了left/center则 direction 的设置不会对其产生影响 -
inline-block、flex、table、grid的布局方向被影响,absolute/fixed、float、margin、padding无任何变化。
为了页面能够在 RTL 布局时正常呈现,我们需要对未被影响的属性调整。目前有以下两种方式可以解决这个问题。