Detached Rulesets 是可执行的样式块容器,非普通变量;必须显式调用(如@rs();)才展开为CSS,声明时不生效,且变量求值发生在定义点而非调用点。

Detached Rulesets 是什么,为什么不能当变量用
Detached Rulesets 在 Less 中本质是「可复用的样式块容器」,不是变量,也不直接生成 CSS。它必须被调用(.call() 或赋值后展开)才会生效。常见错误是写成 @mixin: { color: red; }; 就以为能直接插入,结果编译后完全消失——因为没被引用。
- 它必须显式调用,比如
@mixin();或.my-class { @mixin(); } - 不能在
@media外部直接展开(Less 4+ 支持,但旧版会报错Expected a variable, property or universal selector) - 参数传递时,若传入选择器(如
&:hover),需确保上下文支持嵌套,否则可能生成意外的扁平结构
正确声明和调用 Detached Ruleset 的写法
声明时用括号包裹规则,结尾不加分号;调用时加括号,像函数一样。最简可行示例:
@theme-style: {
background: #f0f0f0;
padding: 1rem;
};
.card {
@theme-style();
}
编译后就是:.card { background: #f0f0f0; padding: 1rem; }。注意三点:
- 声明里不能出现未定义变量(如
@color),除非它已在作用域中声明或通过参数传入 - 调用位置决定生成的选择器层级——
@theme-style();在.card内,就自动继承父级上下文 - 如果想让 ruleset 自带命名空间(比如避免污染全局),可配合
#{...}插值或封装成带前缀的 mixin
带参数的 Detached Ruleset 怎么传选择器和属性
参数可以是值、选择器甚至整个规则块,但需用 @arguments 或具名参数接收。典型场景:动态生成主题变体。
立即学习“前端免费学习笔记(深入)”;
@button-variant: (@bg, @text) {
background-color: @bg;
color: @text;
&:hover {
opacity: 0.8;
}
};
.btn-primary {
@button-variant(#007bff, white);
}
.btn-danger {
@button-variant(#dc3545, white);
}
关键限制:
- 参数不能是纯选择器字符串(如
"&:focus"),必须是合法 Less 语法结构;想动态控制伪类,得用条件判断(when)或拆成多个 ruleset - 若参数含
&,调用时需确保在嵌套上下文中,否则&会解析为空,导致:hover变成孤立规则而报错 - 性能上无额外开销,但过度嵌套 ruleset 调用(如循环中多次展开)可能拖慢编译,建议只用于逻辑分组,非运行时动态
和普通 mixin 的核心区别在哪
Detached Ruleset 和 .mixin() 最大差异在于「延迟求值」和「作用域快照」:前者在声明时捕获当前变量值,后者在调用时才读取变量。比如:
@color: blue;
@rs: { color: @color; };
@color: red;
.test { @rs(); }
结果是 color: blue;(ruleset 捕获了声明时的 @color);而 mixin 会输出 red。这个特性容易被忽略,尤其在配置文件拆分、主题切换等场景中——你以为改了顶层变量就能全局生效,实际 ruleset 已固化旧值。
另一个坑:Detached Ruleset 无法用 !default 覆盖参数默认值,也不支持 guarded 条件,复杂逻辑仍得退回 mixin。


















