Less Guard必须写在mixin定义中,仅编译期生效,语法位置严格;正确结构为.mixin(@arg) when (条件) { ... },多分支靠同名mixin重载实现,类型判断应使用isnumber()等内置函数,避免运行时误用。

Guard必须写在mixin定义里,不能单独用在规则块中
Less Guard不是JavaScript的if,它只在编译期起作用,且语法位置极其严格。写错位置(比如直接放在.card { ... }里),Less会完全忽略Guard,退化成无条件执行——你写的when (@theme = dark)根本不会生效,但也不会报错,只会静默失效。
正确结构只有这一种:.mixin-name(@arg) when (条件) { ... }。多个条件用逗号分隔,表示“与”;同名mixin配不同Guard,才表示“或”。
- 错误写法:
.card { background: #fff; when (@theme = dark) { background: #1a1a1a; } }→ 编译失败或被跳过 - 正确写法:
.card-theme(@theme) when (@theme = dark) { background: #1a1a1a; color: #fff; } - 多分支要靠重载:
.card-theme(@theme) when (@theme = light) { ... }和.card-theme(@theme) when (@theme = dark) { ... }必须共存
类型判断和逻辑取反要用内置函数,别手写字符串比较
Guard里的=是严格相等,但@theme = "dark"这种写法极易出错:如果@theme是变量而非字符串字面量,比较会失败;更危险的是,Less对单位、颜色、数字的隐式转换不一致,12px = 12为false。
应优先使用isnumber()、iscolor()、isstring()等内置类型判断函数,配合not取反。它们在编译期可确定,稳定可靠。
立即学习“前端免费学习笔记(深入)”;
- 安全写法:
.size(@s) when (isnumber(@s)) and (not isunit(@s, %)) { font-size: @s * 1px; } - 避免:
.size(@s) when (@s > 10) { ... }—— 若@s是12px,比较会因单位不匹配失败 - 主题判断推荐:
.theme(@t) when (isstring(@t)) and (@t = dark) { ... },双重防护
Guard和参数mixin要正交拆分,别把尺寸/状态/变体全塞进一个mixin
常见翻车点是定义一个巨型mixin如.button(@size, @variant, @state),再给它加一堆Guard分支。结果一加新组合就爆炸:新增xl尺寸+ghost变体+loading状态,就得补8个Guard分支,维护成本指数上升。
真正可扩展的做法是让Guard只管“要不要输出”,而参数负责“输出什么”。尺寸、状态、变体各自独立封装,调用时链式组合:
-
.btn-base() { ... }—— 公共基础样式 .btn-size(@s) when (@s = small) { height: 24px; padding: 0 8px; }.btn-state(@s) when (@s = disabled) { opacity: 0.6; cursor: not-allowed; }- 调用:
.btn-base(); .btn-size(medium); .btn-state(hover);
这样每个Guard只承担单一职责,新增变体只需加一个mixin,不影响其他逻辑。
Guard不解决运行时切换,多主题方案得靠编译时分离文件
有人想用Guard实现JS控制的主题切换,比如document.body.setAttribute('data-theme', 'dark')再指望when (@theme = dark)响应——这行不通。Guard在编译时已固化,生成的CSS里只有dark或light其中一套,没有运行时分支。
若需多主题,必须提前准备好theme-dark.less和theme-light.less,各自@import对应变量,再分别编译为独立CSS文件,由HTML或构建工具按需加载。
容易被忽略的关键点:Guard本身不产生额外选择器,但它会让同一份mixin展开多次。比如.card-theme(dark)和.card-theme(light)各调用一次,就会生成两套独立CSS规则——若滥用,CSS体积会快速膨胀。务必确认每个Guard分支确实有差异化输出,而不是仅改了个颜色值(那种情况该用变量)。


















