Less 原生不支持 each() 函数,需用递归 mixin 模拟遍历;颜色须定义为变量(如 @blue: #3b82f6),再通过 @@name 动态引用,配合 extract() 和守卫实现安全调色板生成。

Less 的 each() 函数不支持原生遍历颜色列表
Less 本身没有内置的 each() 函数——这是常见误解。你看到的 each() 通常来自第三方插件(如 less-plugin-lists),或被误认为是 Sass 的语法。原生 Less 只提供 .each() 混合(mixin)的模拟写法,依赖递归和守卫(guards)实现“伪遍历”。直接写 each(@colors, ...) 会报错:Unrecognised input。
用递归 mixin 模拟遍历生成调色板 CSS
核心思路:把颜色列表定义为一个空格分隔的字符串(Less 不支持数组,但支持 space-separated list),然后用带索引的递归 mixin 逐项提取、生成规则。适合生成 .bg-blue-50、.text-indigo-600 这类 BEM 风格工具类。
-
@colors: "blue red indigo teal gray"—— 必须用字符串,不能用括号或逗号 - 递归 mixin 需含两个参数:
@list(剩余未处理的颜色名)和@i(当前序号,用于生成 class 后缀) - 用
extract()提取首项,length()+slice()推进列表,避免无限循环 - 每个颜色生成多档亮度(如 50/100/200/…/900),需嵌套另一层循环(可用固定档位 mixin 或硬编码)
.make-palette(@list, @i: 1) when (length(@list) >= @i) {
@color-name: extract(@list, @i);
.bg-@{color-name}-50 { background-color: lighten(~'@{color-name}', 48%); }
.bg-@{color-name}-100 { background-color: lighten(~'@{color-name}', 40%); }
.text-@{color-name}-600 { color: darken(~'@{color-name}', 20%); }
.make-palette(@list, (@i + 1));
}
.make-palette("blue red indigo");
为什么不用 @import 或 JS 插件?
引入外部插件(如 less-plugin-lists)看似省事,但实际带来三类问题:
- 构建链路断裂:Webpack/Vite 的 less-loader 默认不启用插件,需额外配置
lessOptions.plugins,且不同环境易漏配 - 调试困难:插件生成的 CSS 行号与源 Less 文件脱节,报错定位慢
- 颜色解析风险:插件的
each()若尝试直接解析blue字符串为颜色值,会失败——Less 中blue是变量名,不是颜色字面量;必须显式写成@blue: #3b82f6并引用@blue
真正可控的调色板方案:颜色变量 + 循环 mixin
把颜色定义为变量,再用递归遍历变量名列表,是最稳定的做法。这样既能用 lighten()/darken(),又避免字符串到颜色的隐式转换失败。
立即学习“前端免费学习笔记(深入)”;
- 先定义:
@blue: #3b82f6; @red: #ef4444; @indigo: #6366f1; - 再建变量名列表:
@color-names: blue red indigo;(无引号!这是 space-separated list) - 递归时用
extract(@color-names, @i)拿到blue,再用@@color-name动态访问变量@blue - 注意:
@@color-name是 Less 的“双重变量引用”,等价于@blue,不是字符串拼接
.make-palette(@names, @i: 1) when (length(@names) >= @i) {
@name: extract(@names, @i);
@color: @@name;
.bg-@{name}-50 { background-color: lighten(@color, 48%); }
.bg-@{name}-900 { background-color: darken(@color, 40%); }
.make-palette(@names, (@i + 1));
}
.make-palette(blue red indigo);
动态变量引用这一步最容易漏掉,写成 @color-name 或 ~'@{@name}' 都不行——只有 @@name 有效。


















