必须在上设dir="rtl",否则光标、Tab流、Flex轴向、滚动条等关键行为不翻转;混排内容须用隔离,CSS需用逻辑属性替代物理值,且lang必须同步设置。

用 dir 属性 + [dir="rtl"] 选择器做基础隔离
直接依赖 html[dir="rtl"] 或 body[dir="rtl"] 是最稳妥的起点,避免用 direction: rtl 覆盖整个文档流——它会干扰表单控件、数字排版和内联元素渲染。SCSS 里应把 RTL 样式写成独立作用域:
$dir: "ltr";
[dir="rtl"] {
@include rtl();
}
@mixin rtl() {
// 所有 RTL 专用规则放这里
.icon { margin-left: 0; margin-right: 8px; }
.text-align { text-align: right; }
}
关键点是:不写 [dir="ltr"],也不在根级设 direction,让 LTR 成为默认流;RTL 只做「覆盖」,不是「切换」。
用 logical 属性替代 left/right 硬编码
SCSS 本身不解析逻辑属性,但你可以用变量 + @if 模拟行为,尤其适合 padding/margin/border 方向。硬写 margin-left 在 RTL 下必然出错,而用逻辑命名可提前规避:
$spacing-inline-start: if($dir == "rtl", "margin-right", "margin-left");- 编译后生成真实 CSS 时,
#{\$spacing-inline-start}: 12px;→margin-right: 12px;(RTL) - 更推荐方案:直接用原生
margin-inline-start,现代浏览器支持良好,SCSS 不需干预
注意:float: left 必须改为 float: inline-start,否则 RTL 下图标会跑到左边而非内容起始侧。
处理 transform: translateX() 和 background-position 这类隐式方向值
这些属性不响应 dir,必须显式判断。比如一个从右滑入的 toast 动画:
.toast {
transform: translateX(if($dir == "rtl", 100%, -100%));
}
常见坑:
-
background-position: right top→ RTL 下仍停在“视觉右侧”,应改用background-position: end top(end对应inline-end) -
text-indent若用于悬挂缩进,RTL 下需用text-indent: -1em配合direction: rtl,但更稳的是用inset-inline-start - 伪元素
::before的left: 0在 RTL 中要对应inset-inline-start: 0
避免 @at-root 和嵌套破坏 RTL 选择器优先级
SCSS 嵌套容易让 [dir="rtl"] .btn 变成 [dir="rtl"] .container .btn,导致权重升高、难以覆盖。错误写法:
[dir="rtl"] {
.container {
.btn { margin-left: 0; } // 实际生成 [dir="rtl"] .container .btn,太具体
}
}
正确做法是保持 RTL 选择器扁平,用 @at-root 提升层级,或拆出 mixin:
@mixin rtl-btn {
margin-left: 0;
margin-right: 8px;
}
[dir="rtl"] .btn {
@include rtl-btn;
}
复杂组件如分页、日期选择器,RTL 规则常需重写布局逻辑,此时别强求“一份 SCSS 编译两套”,宁可分开维护 _pagination.ltr.scss 和 _pagination.rtl.scss,用构建工具按需引入。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











