Sass变量需配合@if生成direction、text-align、float等规则,定义全局$lang-dir变量并用@mixin封装margin/padding翻转逻辑,避免@extend和硬编码left/right,确保编译时精准输出。

怎么用 Sass 变量控制 LTR/RTL 方向逻辑
不能靠 direction 属性一加就完事——它只影响文本流和光标行为,不翻转 margin、padding、float 这些盒模型属性。Sass 的价值在于编译时把方向逻辑固化进 CSS,避免运行时闪动或第三方组件不响应。
核心做法是定义一个顶层变量,再用 @if 生成对应规则:
$lang-dir: rtl;<br>.btn {<br> direction: $lang-dir;<br> text-align: if($lang-dir == rtl, right, left);<br> float: if($lang-dir == rtl, right, left);<br>}-
$lang-dir必须在全局作用域定义,不能在嵌套选择器里重声明,否则后续@if判断会失效 - 别用
@extend复用方向规则——它不感知上下文,%align-right在 RTL 下还是text-align: right,实际该是start - 如果项目需支持多语言打包(如同时输出 zh.css / ar.css),建议按语言拆文件,而非在一个文件里塞满
@if $lang == "ar"分支,否则未使用规则仍会进最终 CSS
margin/padding 等物理属性怎么安全翻转
写 margin-left: 16px 在 RTL 下必然错位,但直接换 margin-inline-start 兼容性差(Safari 14- 不支持,旧 WebView 行为不一致)。Sass 封装混合宏是最稳妥的中间方案。
示例:
立即学习“前端免费学习笔记(深入)”;
@mixin rtl-margin($val) {<br> margin-left: if($lang-dir == rtl, $val, 0);<br> margin-right: if($lang-dir == rtl, 0, $val);<br>}<br>.card { @include rtl-margin(16px); }- 不要用
margin-inline-start替代——它无法优雅降级,且在部分 Android WebView 中触发 layout shift - 如果用了
float: left,必须同样用if()控制,否则 RTL 下元素完全错位(float不受direction影响) - 图标类、背景定位等含方向语义的地方,也得走同样逻辑,比如
background-position: if($lang-dir == rtl, right, left) 50%
:lang() 和 html[lang] 选择器该怎么配合 Sass 使用
:lang() 是运行时匹配,html[lang] 是静态属性匹配,两者目的不同:前者适合内容级微调(如段落字间距),后者适合整体布局切换(如字体栈、行高)。Sass 不能替代它们,但能减少重复声明。
- 别在
p:lang(zh)里定义 CSS 变量——变量不会继承到子元素,必须写成:lang(zh) { --text-spacing: 0; } - 若需为多个 RTL 语言(
ar、he、fa)共用一套样式,用 SCSS 函数生成组合选择器:#{lang(ar, he, fa)} { .header { direction: rtl; } } -
html[lang="zh-Hans"]和html[lang="zh-CN"]字符串不同,但语义等价,Sass 里得显式列出,不能只靠html[lang^="zh"]覆盖——后者对zh-Hans无效
为什么不能只靠 [dir="rtl"] 做全局切换
局部加 [dir="rtl"](比如只给 <body> 或某个 <div>)会导致浏览器底层行为异常:Safari 光标移动错乱、Chrome getSelection() 返回反向范围、屏幕阅读器读音调错误。真正起效的前提是 <html lang="ar" dir="rtl">。
-
dir必须设在<html>根元素上,否则表单 placeholder 对齐、双击选词、滚动条位置等均不可靠 - 第三方组件(如 Ant Design 旧版 DatePicker)常硬编码
left: 0,Sass 变量插不进去,只能靠[dir="rtl"] .ant-picker-dropdown手动覆盖 - 伪元素箭头(如
::before { content: "→" })在 RTL 下需重写整个content值,不能只靠transform: scaleX(-1)——会把数字、标点全镜像
最易被忽略的是:字体排版细节(如中英混排间隙、CJK 行高)和 dir 无关,得靠 :lang() + CSS 变量单独调,不能指望 Sass 变量自动解决。


















