Less中.each()要求@list必须是明确列表而非字符串,因其仅接受List或Map;传入字符串如"1,2,3"会被视为单个值导致循环仅执行一次;正确方式是用range(1,12)生成数字列表或显式声明@nums: 1,2,3。

Less中.each()循环生成网格类名时,为什么@list必须是明确的列表而非字符串?
因为.each()只接受List(逗号分隔的值序列)或Map作为第一个参数,传入字符串(如"1,2,3")会被当作单个字符串值处理,导致循环只执行一次且@item等于整个字符串。常见错误是误用range(1, 12)直接传给.each()——它返回的是一个List,但需确保未被意外转成字符串。
正确做法:
- 用
range(1, 12)生成数字列表,它返回1, 2, 3, ..., 12(逗号分隔的Less List) - 避免中间拼接:
@str: "1,2,3"; .each(@str, ...)❌;应写为@nums: 1, 2, 3; .each(@nums, ...)✅ - 若需动态范围,优先用
range(),不用extract()或length()手动构造
用range()配合.each()生成.col-1到.col-12的完整示例
Less不支持for-in或传统索引循环,range() + .each()是最简洁可靠的批量方式。注意range()包含起止值,range(1, 12)生成12个元素。
.col-12 {
width: 100%;
}
.each(range(1, 12), {
@i: @value;
.col-@{i} {
width: (@i * 100% / 12);
}
});编译后会输出.col-1(8.333%)、.col-2(16.666%)…….col-12(100%)。关键点:
立即学习“前端免费学习笔记(深入)”;
-
@value是range()当前项的数值,直接可用,无需extract() -
@{i}用于变量插值,不可写成.col-@i(Less会报错) - 除法要加括号
(@i * 100% / 12),否则@i * 100% / 12可能被解析为单位运算错误
生成响应式网格类(如.col-md-4)时,如何嵌套两层.each()?
Less不支持多层for循环语法,但可借助嵌套.each()实现:外层遍历断点,内层遍历列数。注意作用域——内层@value会覆盖外层,需提前用@bp、@cols重命名。
.each(md, lg, xl, {
@bp: @value;
.each(range(1, 12), {
@cols: @value;
.col-@{bp}-@{cols} {
flex: 0 0 (@cols * 100% / 12);
max-width: (@cols * 100% / 12);
}
});
});这会生成.col-md-1、.col-md-2…….col-xl-12共36个类。容易踩的坑:
- 外层
.each()传入md, lg, xl必须是逗号分隔的标识符,不能加引号("md", "lg"会被当字符串) - 内层
@value和外层同名,必须重命名,否则内层会污染外层上下文 - 如果某断点需不同列数范围(如
xl支持1–24列),需拆分为独立.each()块,不能共用range()
为什么range(1, 12)在某些Less版本里不生效?
range()是Less 4.0+引入的内置函数,低于此版本(如3.13.x)会报undefined function range。检查方式:lessc --version。旧项目升级前需确认构建工具链兼容性。
降级兼容方案(Less 3.x):
- 手写列表:
@cols: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; - 用递归mixin模拟range(复杂且易栈溢出,仅限小范围)
- 改用PostCSS +
postcss-nested+postcss-for替代Less循环(更现代,但需切换工具链)
真正麻烦的不是语法,而是团队协作中有人本地lessc版本低,导致CI编译通过但本地热更新失效——这类问题往往卡在环境一致性上。


















