dir属性+ltr/rtl媒体查询不可靠,应通过Less布尔变量@is-rtl配合if()函数在编译期显式控制左右方向样式,并封装为mixin避免作用域丢失。

用 dir 属性 + ltr/rtl 媒体查询不够可靠
Less 本身不识别文本方向,@media (prefers-direction: rtl) 浏览器支持极差(仅 Safari 17.4+ 实验性支持),不能作为主力方案。真实项目里得靠显式切换:在 HTML 根节点加 dir="rtl",然后用 Less 变量或 mixin 控制生成逻辑。
用 is-rtl 变量控制方向逻辑分支
最稳的方式是定义一个布尔变量,配合 if() 函数做条件编译。Less 3.5+ 支持 if(),但注意它只在编译期生效,不是运行时 JS 判断:
@is-rtl: true;
.text {
text-align: if(@is-rtl, right, left);
padding-left: if(@is-rtl, 0, 12px);
padding-right: if(@is-rtl, 12px, 0);
margin-left: if(@is-rtl, auto, 8px);
margin-right: if(@is-rtl, 8px, auto);
}
关键点:
-
if()的三个参数必须全写,不能省略 false 分支 - 所有涉及左右的属性(
margin、padding、border、float、text-align、direction)都得显式处理 - 别依赖
logical属性(如margin-inline-start),它们在旧版浏览器里 fallback 不可控
用 .rtl 类名包裹生成 RTL 规则块
更灵活的做法是把 RTL 样式单独抽成类,避免全局污染,也方便动态切换:
立即学习“前端免费学习笔记(深入)”;
@is-rtl: true;
// 基础 LTR
.button {
padding: 8px 16px;
border-radius: 4px 0 0 4px;
}
// RTL 覆盖
if(@is-rtl) {
.rtl {
.button {
padding: 8px 16px;
border-radius: 0 4px 4px 0;
// 注意:这里 padding 左右值没变,但视觉上“起始”已翻转
// 所以真正要改的是语义,不是单纯 swap left/right
}
}
}
常见陷阱:
- 直接 swap
padding-left和padding-right值会出错——比如图标在左侧的输入框,RTL 下图标应在右侧,但 padding 值未必对称 - 用
transform: scaleX(-1)翻转整个元素,会把文字也镜像,不可取 - 某些组件(如 slider、date picker)内部结构复杂,纯 CSS RTL 很难覆盖,得结合 JS 控制 DOM 顺序
处理伪元素和图标方向
箭头类图标、::before/::after 生成内容最容易漏掉 RTL 适配:
.accordion-toggle::after {
content: if(@is-rtl, "◀", "▶");
margin-left: if(@is-rtl, 0, 8px);
margin-right: if(@is-rtl, 8px, 0);
}
.icon-chevron-left {
background-image: if(@is-rtl, url("chevron-right.svg"), url("chevron-left.svg"));
}
注意:
- SVG 图标路径最好用
transform: rotateY(180deg)替代换图,减少资源请求 -
::placeholder、::selection等伪元素不继承dir,需单独声明direction: rtl - 字体本身(如阿拉伯数字、希伯来文)无需额外设置,但确保用了支持这些字符的字体栈
.modal > .header 里忘记重新引用 @is-rtl,会导致子选择器仍按 LTR 输出。建议把方向判断逻辑封装进 mixin,强制每次调用都显式传参。


















