Less 的 when 是编译期守卫,非运行时条件;必须依附 Mixin 或嵌套选择器,不可单独使用;类型需显式统一,须配默认分支,且仅响应编译时变量值。

Less 的 when 不是运行时 if,它只在编译期匹配变量值生成静态 CSS;想靠它响应点击、媒体查询或 JS 动态切换?做不到。
Guard 必须配合 Mixin 或嵌套选择器使用,不能单独写在规则里
常见错误是直接写 .btn when (@size = "large") { ... },这会报错。Less 要求 when 必须依附于一个可展开的结构:要么是带参数的 Mixin,要么是带 & 的嵌套选择器。
- 正确写法(Mixin 形式):
.btn(@size) when (@size = "large") { padding: 16px 32px; },调用时写.btn("large"); - 正确写法(嵌套形式):
.btn { & when (@size = "large") { padding: 16px 32px; } } - 错误写法:
.btn when (@size = "large") { ... }—— 解析器不认识这种语法 - 错误写法:
.btn { width: when (@fluid) { 100% } else { 800px }; }—— Less 不支持内联三元,when不能当表达式用
字符串、数字、关键字混用时类型不匹配会导致守卫静默失效
@size: 16 和 @size: "16" 在 when 里不相等,比较前必须统一类型。Less 不会自动转换,也不会报错,只是跳过整个分支。
- 用
unit()转换单位:.font(@n) when (unit(@n, px) > 14px) { font-size: @n; } - 用
isstring()/isnumber()做前置判断:.pad(@val) when (isnumber(@val)) { padding: @val * 1px; } - 字面量统一加引号:
when (@theme = "dark")比when (@theme = dark)更安全,后者会把dark当变量查 - 未定义变量参与比较(如
@mode没声明)会直接让守卫失效,建议顶层初始化:@mode: "default";
多个 when 分支按定义顺序匹配,没有隐式 else
Less 遇到第一个为 true 的 when 就停止,后面不管有没有更精确的条件都不会再检查。漏掉兜底分支,就可能什么 CSS 都不输出。
立即学习“前端免费学习笔记(深入)”;
- 把最具体的条件放前面,比如:
when (@theme = "dark") and (@density = "compact") - 否定条件慎用:
when not (@size = "small")会匹配所有非 small 的值,包括未定义值,容易误伤 - 显式兜底推荐写法:
when not (@size = "small"), not (@size = "large")(逗号表示 or),等价于 “既不是 small 也不是 large” - 一定要提供无
when的默认版本:.btn(@size) { /* 默认样式 */ },否则@size是其他值时整个 mixin 不生效
Guard 无法感知 CSS 运行时状态,别试图让它响应 media 或伪类
when 只看编译时变量值,@media、:hover、data-* 属性、JS 修改的 class 都不影响它。想实现响应式切换?得靠预设断点变量 + CLI 参数传入,而不是在 when 里写 @media-width > 768px。
- 错误:
& when (@media-width > 768px) { ... }——@media-width不是 Less 变量,编译期不存在 - 可行做法:构建时通过
--variable=@screen:md传参,再用when (@screen = "md") - 伪类无效:
& when (hover) { ... }不合法,hover不是变量,也不是 Less 函数 - 真正能用的只有编译期确定值:已声明变量、字面量、
isnumber()等内置函数返回结果
Guard 的复杂性不在语法,而在它和编译流程的耦合——你写的每个 when 都是在告诉编译器“如果这个变量等于 X,就生成这部分 CSS”,而不是“运行时判断 X 再决定”。变量没初始化、类型没对齐、兜底没写全,都会导致样式莫名消失,且控制台完全没提示。


















