Less 中 each() 无法直接遍历数字范围,必须配合 range(1, 12)(6.0+)或手动列表;生成栅格类时需用 each() + mixin guard;断点循环应结合 index() 与 extract(),避免误用字符串作索引;动态类易致 CSS 膨胀,应按需裁剪。

Less 中 each() 无法直接遍历数字范围,必须配合 range() 或手动列表
Less 原生不支持类似 Sass 的 @for 数字循环,each() 只能遍历已存在的 list(数组)。想生成从 col-1 到 col-12 的网格类,你不能写 each(1..12, ...)——这会报错 ParseError: missing opening '('。正确做法是先用 range(1, 12) 生成 list,再传给 each()。
注意:range() 返回的是从起始到结束(含)的整数 list,但 Less 6.0+ 才原生支持;旧版需手动定义或借助第三方函数库(如 less-plugin-lists),否则得硬编码 @cols: 1, 2, 3, ..., 12。
-
range(1, 12)在 Less 6.0+ 中安全可用;低于该版本请改用@grid-columns: 12;+ 手动 list 或预编译脚本生成 - 若用
extract()辅助取值(比如从配置 map 中按序提取断点),它只负责“按索引取元素”,不参与循环逻辑 - 避免在
each()回调里嵌套另一层each()—— Less 编译器容易栈溢出或报Maximum call stack size exceeded
用 each() + range() 生成响应式栅格类的最小可行写法
下面这段代码能在 Less 6.0+ 中直接编译出 .col-1 ~ .col-12,并自动计算宽度(假设 12 列等分):
.make-grid-columns() {
.make-grid-column(@index) when (@index > 0) {
@width: (100% / 12) * @index;
.col-@{index} {
flex: 0 0 @width;
max-width: @width;
}
}
each(range(1, 12), .make-grid-column);
}关键点:
-
each()第二个参数是 mixin 名(不带括号),不是调用;它会把 list 中每个值依次传入.make-grid-column的第一个参数 -
.make-grid-column必须带 guard(when (@index > 0))防止递归失控,虽然range()已保证正整数,但这是防御性习惯 - 别在
each()外部定义变量并期望它在回调中可变——Less 是静态求值,@index是每次调用时的局部参数,不是全局迭代器
当需要多断点(sm/md/lg)时,extract() 的典型误用与正解
有人试图用 extract(@breakpoints, @i) 配合 each() 实现断点循环,结果发现所有生成的媒体查询都用了同一个断点值。问题在于:each() 的回调中没有隐式索引变量 @i,extract() 的第二个参数必须是具体数字(如 1, 2),不能是当前遍历项。
正确方式是:把断点名和值一起做成 map,用 each() 遍历 map,再用 extract() 提取对应值(如果 map 结构复杂);但更直白的做法是直接遍历断点名 list,并用 guard 匹配:
@breakpoints: sm, md, lg;
@breakpoint-values: 576px, 768px, 992px;
<p>each(@breakpoints, {
@bp-index: index(@breakpoints, @value);
@bp-width: extract(@breakpoint-values, @bp-index);
@media (min-width: @bp-width) {
.col-@{value}-1 { flex: 0 0 8.333%; }
// ... 其他列
}
});-
index()返回当前@value在 list 中的位置(从 1 开始),才能喂给extract() - 不要写
extract(@breakpoint-values, @value)——@value是字符串sm,不是数字索引 - 如果断点 map 是
(sm: 576px, md: 768px)形式,应改用keys()+values()分离处理,而非硬凑extract()
性能与维护陷阱:动态生成太多类会导致 CSS 体积激增
用 each() 生成 12 列 × 4 断点 × 每列 offset/pull/push 等变体,轻松产出上千行 CSS。开发时看着方便,上线后可能让 CSS 文件膨胀 200KB+。
- 优先用 class 组合替代预设(如
.col-6 .offset-3而非.col-6-offset-3),减少组合爆炸 - Less 编译时无法做 tree-shaking,未使用的
.col-11也会被写出;建议按项目实际用到的列数裁剪range()范围 -
extract()查找开销极小,但若在深层嵌套 mixin 中高频调用(如每像素计算),可能拖慢编译速度——这种场景更适合用 JS 插件预处理
真正难的不是写出来,而是判断哪些类该保留、哪些该删。多数项目根本用不满 12 列全断点组合,硬套模板反而增加维护成本。

















