less 3.x 不支持内置 .each() 函数,需用递归 mixin 模拟遍历,依赖 extract() 和 slice() 提取首项与剩余项,并以 length() 判断终止条件。

Less 3.x里.each()根本不存在,别被旧文档误导
Less 3.x 没有内置的 .each() 或 list-loop() 函数。所谓“List函数遍历”,实际依赖的是 each() 混合(mixin)——但它不是语言原生能力,而是社区手动实现的递归 mixin。很多搜索结果把 Less 4.x 的新特性或第三方插件功能错标为 3.x 支持,导致你写 .each(@list, ...) 直接报错 Unrecognised input。
用递归 mixin 模拟 list 遍历:核心写法和必须参数
Less 3.x 只能靠自己展开列表,本质是递归调用 mixin,每次处理第一个元素,再把剩余元素传给下一层。关键点:
-
@list必须是逗号分隔的值(如red, blue, green),不能是空格分隔或带括号的嵌套结构 - 必须显式提取首项:
extract(@list, 1),索引从 1 开始 - 必须显式截取剩余项:
slice(@list, 2),从第 2 个起切到末尾 - 递归终止条件:用
when (length(@list) = 1)或when (length(@list) = 0)控制
.for-each(@list) when (length(@list) > 0) {
@item: extract(@list, 1);
.my-class-@{item} { color: @item; }
.for-each(slice(@list, 2));
}
.for-each(@list) when (length(@list) = 0) {}
// 调用
.for-each(red, blue, green);
常见翻车点:空格、引号、嵌套列表全会崩
Less 3.x 对 list 解析极其脆弱,以下写法都会让 extract() 或 slice() 失效:
- 写成
red blue green(空格分隔)→ Less 当成单个变量名,不是 list - 写成
"red", "blue"(加引号)→ 引号被当作文本字面量,extract()返回带引号字符串,生成类名变成.my-class-"red" - 写成
(red, blue), (green, yellow)(嵌套)→length()返回 2,但extract(@list, 1)取出来是整个括号组,无法直接用 - list 最后多一个逗号,如
red, blue,→ Less 3.x 会多出一个空元素,length()多 1,extract()可能返回""
性能和维护提醒:别在大列表上硬刚
Less 3.x 递归没有尾调用优化,list 超过 20 项就可能触发编译器栈溢出(错误类似 Recursive call of mixin)。更现实的做法:
- 把生成逻辑移到构建层(比如用 PostCSS 插件处理 class 列表)
- 若必须用 Less,把 list 拆成多个小段,每段 ≤10 项,分别调用
.for-each() - 避免在
@media或嵌套选择器内调用该 mixin——每次调用都会重复展开,CSS 体积指数级增长
真正容易被忽略的,是 slice() 在 Less 3.12+ 才稳定支持;低于这个版本得自己手写 .rest() mixin 模拟,而且要额外处理 length 为 0 的边界。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











