Detached ruleset 是一种可赋值、可传递、延迟求值的样式块容器,本质是未编译进输出 CSS 的规则集合;它不自动展开,需显式调用(如 +@ruleset 或 @ruleset())才生成样式,常用于封装条件样式、主题逻辑或作为 mixin 参数复用。

什么是 detach ruleset?它不是函数也不是 mixin
Less 的 detach ruleset 是一种“可赋值、可传递、延迟求值”的样式块容器,本质是未被编译进输出 CSS 的规则集合。它不自动展开,也不会像 .mixin() 那样直接生成样式——你得显式调用它(比如用括号 () 或 + 操作符)才会触发渲染。
常见误用是把它当 mixins 用却忘了调用,结果样式完全不出现;或者在变量作用域外访问了内部变量,导致编译报错 Variable @xxx is undefined。
典型声明写法:
@btn-base: {
display: inline-flex;
align-items: center;
padding: 0.5em 1em;
border: none;
font-size: 1rem;
};
怎么把 detach ruleset 当作参数传给 mixin
这是复用最实用的场景:把一整套样式逻辑封装成 ruleset,再交给不同上下文(如 dark mode、禁用态、尺寸变体)去叠加或修改。
立即学习“前端免费学习笔记(深入)”;
关键点在于:mixin 参数必须声明为 @ruleset 类型(Less 4.0+),且调用时需用 + 显式展开(否则只是赋值,不渲染):
-
+是强制展开 ruleset 的唯一可靠方式;()在某些嵌套层级下会失效 - ruleset 内部引用的变量,若来自调用方作用域,必须提前用
@{...}插值或通过 mixin 参数透传 - 不能在
@media或:hover等嵌套选择器里直接定义 ruleset 并期望它继承父级变量——它只捕获定义时的作用域
示例:
.button-variant(@color, @ruleset) {
background-color: @color;
+@ruleset; // 必须加 +
}
.primary-btn {
.button-variant(#007bff, @btn-base);
}
如何用 detach ruleset 实现条件样式拼接
比起写一堆 if 分支 mixin,用 ruleset 可以更清晰地组合样式逻辑,尤其适合主题切换或状态叠加(如 loading + disabled)。
注意两点:
- 多个 ruleset 拼接要用
+逐个展开,不能用merge或extend——它们不支持 ruleset 合并 - 同名属性会被后展开的 ruleset 覆盖(CSS 层叠规则依然生效),不是“深合并”
- 如果 ruleset 里含
&嵌套,展开位置决定其父选择器上下文,容易意外污染全局
例如构建带 icon 的按钮:
@with-icon: {
& > svg {
margin-right: 0.375em;
width: 1em;
height: 1em;
}
};
.btn-iconic {
+@btn-base;
+@with-icon;
}
为什么 detach ruleset 在复杂主题中比变量 + mixin 更可控
当你有几十个组件要适配 light/dark/high-contrast 三套主题时,靠 @primary-color 这类变量容易漏改,靠 mixin 堆叠又难追溯来源。detach ruleset 把“一套视觉逻辑”真正封装成一个值,可存入 map、可条件取、可测试是否为空:
- 检查 ruleset 是否为空:
isruleset(@theme)返回true或false - 用
extract()从 list 中取 ruleset,配合each()批量注入 - ruleset 不参与 CSS 输出体积统计,但过度嵌套会导致编译慢——尤其是含大量嵌套选择器时
真正容易被忽略的是:ruleset 不会自动继承调用点的 @media 上下文。如果你在 @media (prefers-color-scheme: dark) 里定义 ruleset,它内部不会自动带上该媒体查询;必须手动包裹或由接收它的 mixin 处理。


















