Less原生无each函数,需用递归mixin模拟遍历;官方推荐做法是定义带终止条件(@i > length(@list))的递归mixin,索引从1开始。

Less里根本没有each函数
Less本身不提供each这类高阶遍历函数,你看到的类似写法基本来自第三方插件(如less-plugin-lists)或误将Sass语法套用到Less。原生Less只支持.for()循环(需配合loop mixin)、递归mixin或extract() + length()手动实现“模拟遍历”。直接写each(@list, ...)会报错:Unrecognised input。
用递归mixin模拟数组遍历最可靠
这是官方推荐、零依赖、兼容所有Less版本(>=2.0)的做法。核心思路是:定义一个接收列表和索引的mixin,自身调用自己直到索引越界。
常见错误是忘记终止条件或索引从1开始却用length()比较出错——Less列表索引从1起,length(@list)返回总数,所以终止条件是@i > length(@list)。
.gen-classes(@list, @i: 1) when (@i =< length(@list)) {
@item: extract(@list, @i);
.class-@{item} { color: lighten(red, @i * 10%); }
.gen-classes(@list, (@i + 1));
}
.gen-classes(@list); // 调用入口使用时传入逗号分隔的值:.gen-classes(1px, 2px, 4px);,输出三个类。
立即学习“前端免费学习笔记(深入)”;
为什么不用.for()或loop插件
.for()不是Less内置语法,是某些构建工具(如less-plugin-for)注入的扩展,会导致:
- 在VS Code Less插件中无法语法高亮或校验
- Webpack的
less-loader默认不启用该插件,需额外配置plugins字段 - CI环境容易因插件缺失直接编译失败
而纯递归方案无外部依赖,lessc命令行、Webpack、Vite全兼容,且逻辑透明——你清楚每一步怎么执行、哪条规则生效。
数组元素含空格或特殊字符要加引号
Less解析列表时,逗号是分隔符,但空格、括号、斜杠等会破坏结构。比如gen-classes(10px solid red, 2px dashed blue)会被拆成5项而非2项。
正确做法是用引号包裹每个复合值:
.gen-classes("10px solid red", "2px dashed blue");此时extract()取出来的是带引号字符串,若需作为CSS值直接使用,得用~@{item}做转义;若只是拼类名,用@{item}即可(Less会自动去掉外层引号)。
真正麻烦的不是语法,而是维护性——当你要遍历几十个断点或颜色变量时,递归mixin的调试成本明显高于Sass的@each。这时候该考虑的不是“怎么在Less里硬搞”,而是评估是否值得迁移到更合适处理这类逻辑的工具链。


















