detached ruleset 是 Less 中可复用、可传参的样式块容器,保存已解析的 AST,不接受原始 CSS 字符串;需用 @name: { ... }; 定义并 @name(); 调用,支持定义时作用域和参数传递。

detached ruleset 是什么,它能传 CSS 代码块吗?
detached ruleset 在 Less 中本质是一个可复用、可传递的样式块容器,但它不是字符串模板,也不直接“传递 CSS 代码”。它保存的是已解析的 Less 样式树(AST),所以你不能往里塞未解析的原始 CSS 字符串(比如 "color: red !important;"),否则会报错或被忽略。
- 它支持嵌套规则、变量插值、函数调用、媒体查询等 Less 特性
- 它在调用时才展开,因此可以延迟求值,适合做条件样式封装
- 如果你试图用字符串拼接方式“注入”样式,Less 编译器会在解析阶段就报错:
ParseError: Unexpected token
正确写法:把样式逻辑写成 ruleset 变量,再用括号调用
核心是定义一个带括号的变量,赋值为一组样式声明,然后在需要的地方用 () 调用它:
.my-theme-ruleset: {
color: #333;
font-weight: bold;
@media (max-width: 768px) {
font-size: 14px;
}
}
<p>// 使用
.example {
.my-theme-ruleset();
}</p>-
.my-theme-ruleset:后面的冒号 + 空格 + 大括号,是 Less 的 detached ruleset 语法糖(等价于@my-ruleset: { ... };) - 调用必须加括号:
.my-theme-ruleset();,不加括号只是定义,不会输出任何 CSS - ruleset 内部可以访问外部作用域的变量(如
@primary-color),但不能访问调用点的局部变量(除非显式传参)
如何传参并动态生成样式?
detached ruleset 支持类似函数的参数列表,让样式逻辑更灵活:
@button-styles: {
background-color: @bg;
border: 1px solid @border;
color: @text;
};
<p>.btn-primary {
@button-styles(@bg: #007bff, @border: #007bff, @text: white);
}</p><p>.btn-outline {
@button-styles(@bg: transparent, @border: #6c757d, @text: #6c757d);
}</p>- 参数名必须和 ruleset 内部使用的变量名一致(如
@bg) - 参数顺序无关,但命名要准确;不传的参数会保留其在 ruleset 定义时的默认值(如果有的话)
- 不支持 rest 参数或可选参数语法,缺失参数会导致编译失败:
Variable @bg is undefined - 如果参数本身是 ruleset,也可以嵌套传递,但需注意作用域链——外层 ruleset 里的变量不会自动透传进内层
常见坑:ruleset 和 mixin 混用时的作用域陷阱
很多人误以为 detached ruleset 和 mixin 完全等价,但关键区别在于变量查找时机:
立即学习“前端免费学习笔记(深入)”;
- mixin 展开时,变量按调用位置作用域查找
- detached ruleset 展开时,变量按定义位置作用域查找(即 lexical scope)
@base-color: blue;
<p>.my-ruleset: {
color: @base-color; // ✅ 这里用的是定义时的 @base-color
}</p><p>@base-color: red;</p><p>.test {
.my-ruleset(); // 输出 color: blue,不是 red
}</p>- 如果你希望它响应调用时的变量,得显式传参,或改用 mixin
- ruleset 里不能用
&引用父选择器(如&:hover),会报错;要用&,得写在调用点的选择器内部 - Webpack / Vite 的 less-loader 默认开启 strictMath 等选项,某些旧版 ruleset 写法(如省略分号)可能触发警告,建议每条声明后都加分号
Less 的 detached ruleset 不是 CSS 注入通道,它是带作用域的样式函数。真正难的不是怎么写,而是想清楚「这组样式该在哪定义、依赖哪些上下文、是否需要随调用点变化」——漏掉这点,后面所有传参和复用都会出偏。


















