less 4 的 .each() 不支持数字范围遍历,需用递归 mixin(如 .make-col-classes)生成 .col-1 至 .col-12 类,因其零依赖、可控性强且兼容性好。

Less 4 的 .each() 函数不支持直接遍历数字范围
Less 4.0+ 确实引入了 .each(),但它只接受 list(列表)或 map(键值对),不能像 Sass 那样写 @for $i from 1 through 12。想生成栅格类(如 .col-1 到 .col-12),你得先构造一个数字列表——而 Less 没有内置的 range() 函数。
常见错误是直接写:.each(1..12, { ... }),这会报错:Operation on an invalid type,因为 1..12 不是合法 Less 表达式,也不会自动转成 list。
- 必须手动写
@cols: 1, 2, 3, ..., 12,或用递归 mixin 生成 - 也可以借助第三方插件(如
less-plugin-functions),但会增加构建依赖,不推荐在基础栅格中引入 - Less 4.2+ 支持
extract()和length(),可辅助做索引控制,但依然不能替代 range
用递归 mixin 生成 1–12 的列宽类(推荐方案)
这是最可控、零外部依赖的做法。核心思路:定义一个带计数器的 mixin,在每次调用时输出一条规则,然后调用自身直到达到上限。
.make-col-classes(@i: 1, @n: 12) when (@i =<p>说明:</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板"><img src="https://img.php.cn/upload/webcode/000/000/018/178607072210981.jpg" alt="CSS婚礼策划服务机构宣传网站模板" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板" class="overflowclass">CSS婚礼策划服务机构宣传网站模板</a> <p class="overflowclass">CSS婚礼策划服务机构宣传网站模板是一款适合提供婚礼策划和婚庆服务机构宣传网站模板下载。提示:本模板调用到谷歌字体库,可能会出现页面打开比较缓慢。</p> </div> <a rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div>
-
@i: 1是起始值,@n: 12是总列数,两者都支持传参覆盖 when (@i = 是守卫条件,防止无限递归- 每轮生成
.col-1、.col-2….col-12,宽度按比例计算(如.col-3→25%) - 注意不要漏掉终止调用:
.make-col-classes();,否则不会触发执行
用 list + .each() 实现更语义化的批量生成
如果你偏好显式 list 控制(比如需要跳过某些值、或按非线性序列生成),可以先定义 list 再遍历:
@grid-breakpoints: xs, sm, md, lg, xl;
@grid-columns: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12;
<p>.each(@grid-columns, .(@col) {
.col-@{col} {
flex: 0 0 calc((@col / 12) <em> 100%);
max-width: calc((@col / 12) </em> 100%);
}
});</p><p>// 响应式变体(需配合媒体查询 mixin)
.each(@grid-breakpoints, .(@bp) {
@media (min-width: ~"(@{bp}-breakpoint)") {
.each(@grid-columns, .(@col) {
.col-@{bp}-@{col} {
flex: 0 0 calc((@col / 12) <em> 100%);
max-width: calc((@col / 12) </em> 100%);
}
});
}
});</p>
注意点:
-
.each()的回调参数名(如.(@col))必须带点号和括号,漏掉.会编译失败 - 嵌套
.each()时,内层变量名不能与外层冲突(比如都用@col),否则会被覆盖 -
~"(@{bp}-breakpoint)"是字符串拼接写法,实际需配合变量如@xs-breakpoint: 480px才能生效
性能与维护风险:别在 .each() 里做复杂计算
Less 编译是静态的,所有逻辑都在构建时展开。如果在 .each() 回调里调用多个函数(比如嵌套 percentage()、round()、unit()),不仅可读性差,还可能触发 Less 解析边界问题(如栈溢出或类型推导失败)。
- 栅格宽度建议统一用
calc(),避免percentage(@col / 12)这类旧式写法(Less 4 对除法优先级更严格) - 如果需要四舍五入像素值(如
max-width: 83.3333% → 83.33%),应在 JS 构建层后处理,而非在 Less 里用round(@x, 2)—— 它对小数精度不稳定 - 超过 24 列的栅格系统慎用递归,Less 默认递归深度限制为 128,12 列安全,但 48 列可能触发
Recursive call error
真正麻烦的不是写法,而是当设计师突然说“把断点从 5 个扩到 7 个”,你得同步改 list、改 media 查询、核对所有嵌套层级——这时候手写 list 反而比递归更易定位问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










