less的when是编译期守卫而非运行时条件,仅在编译时根据变量值匹配生成静态css规则,不响应dom事件或媒体查询变化;必须定义在mixin末尾,多守卫用逗号分隔表“或”,条件内用and连接,支持=、!=、>、>=、

Less里没有if语句,when不是运行时判断
Less的when是编译期守卫(guard),不是CSS运行时条件逻辑。它只在Less编译成CSS时起作用,生成的是静态规则,不会产生JS那样的动态分支。如果你期待“页面加载后根据class切换样式”,when做不到——那得靠CSS类名切换或JS控制。
常见错误现象:when写在嵌套选择器里却没生效,或误以为能响应:hover、@media变化;其实它只看变量值是否匹配,不监听DOM或媒体查询变化。
-
when必须跟在.mixin-name()定义末尾,不能单独存在 - 多个
when守卫用逗号分隔,表示“或”关系;同一守卫内用and连接多个条件 - 支持的比较操作符只有
=、!=、>、、<code>>=、,不支持<code>===或正则匹配 - 变量类型要一致:数字
10和字符串"10"不相等,isnumber(10)返回true,但isnumber("10")是false
.button() when (@size = large)怎么写才不报错
守卫语法对空格和括号敏感,when (@size = large)中large未加引号会被当作变量,若未定义就报Variable @large is undefined。正确做法是统一用引号包裹字面量,或用iskeyword()辅助判断。
使用场景:设计系统中按@size变量生成不同尺寸按钮,避免手写多套.btn-sm/.btn-lg规则。
- 写法一(推荐):
.button() when (@size = "large") { padding: 12px 24px; } - 写法二(兼容变量/字面量):
.button() when (iskeyword(@size)) and (@size = large) { ... },前提是@size: large;已声明为关键字 - 别漏掉默认分支:必须提供无
when的兜底定义,否则@size为"small"时整个mixin不生效
多个when分支共存时,顺序和优先级怎么定
Less按定义顺序匹配when分支,遇到第一个为true的就停止,后续守卫不再检查。这和CSS选择器权重无关,纯看mixin定义位置。
性能影响:守卫本身不耗运行时资源,但分支过多会让编译后CSS体积增大;如果只是开关几个属性,用merge或default可能更轻量。
- 先写最具体的条件,比如
when (@theme = "dark") and (@mode = "compact")放前面 - 把
when not (@theme = "light")这类否定守卫放最后,避免遮挡其他分支 - 不要依赖“隐式else”:没匹配到任何
when,且没定义无守卫版本,结果就是该mixin完全不输出CSS
为什么when里用@media或:hover会失效
when只作用于Less变量和函数计算,无法感知CSS伪类、媒体查询或DOM状态。试图写.card() when (hover) { ... }或when (max-width 会直接报语法错误——因为<code>hover和max-width根本不是Less变量。
容易被忽略的地方:有人把@media写进守卫条件,其实是想做响应式变体,但正确路径是用@media包裹整个mixin调用,而不是塞进when里。
- 错误:
.box() when (@mq = tablet) { @media (max-width: 768px) { ... } }—— 守卫无法触发媒体查询生成 - 正确:
@media (max-width: 768px) { .box(); },再配合@mq: tablet;在不同文件中切换 - 真需要条件性媒体查询?只能靠构建脚本预处理Less入口文件,或改用PostCSS+插件
复杂点在于:守卫看起来像编程逻辑,但它本质是CSS预处理器的模板分支,所有决策都固化在编译那一刻。你写的每个when,最终都变成几段静态CSS规则,不存在“运行时重新计算”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











