less 中无法使用 for 循环,需用带终止条件的递归混入模拟遍历,否则会因无限递归导致编译错误;典型做法是传入索引 @i 和上限 @n,通过守卫判断 @i

Less 里没有 for 循环,但可以用递归混入模拟遍历
Less 原生不支持 for、@each 这类迭代语法,Sass 的 @each 或 @for 在 Less 中无法直接替代。想批量生成类(比如 .mt-1 到 .mt-20),唯一可行路径是递归混入(recursive mixin)——靠自身调用 + 终止条件控制展开深度。
递归混入必须带终止条件,否则编译报错
Less 编译器对递归无深度限制,但没显式退出逻辑就会无限展开,最终触发 Maximum call stack size exceeded 错误。关键在于用守卫(guard)或算术比较切断递归链。
常见写法是传入当前索引 @i 和上限 @n,每次调用时 @i + 1,并用 when (@i = 控制是否继续:
.generate-mt(@i: 1, @n: 20) when (@i =<p>注意两点:<br>• 守卫 <code>when (@i = 必须写在混入定义末尾,不能丢<br>• 递归调用参数要加括号,如 <code>(@i + 1)</code>,否则 Less 会把 <code>@i + 1</code> 当变量名解析</code></p><h3>生成带单位的数值列表时,单位处理容易出错</h3><p>Less 不支持运行时拼接单位(比如 <code>@i px</code> 会报错),必须用插值 <code>@{i}px</code> 或乘法转换单位(<code>@i * 1px</code>)。后者更安全,尤其涉及计算时:</p>
-
.mt-@{i} { margin-top: (@i * 4px); }✅ 安全,自动转为像素值 -
.mt-@{i} { margin-top: @{i}px; }⚠️ 若@i是表达式(如@i + 1),插值会原样输出字符串,导致 CSS 无效 -
.mt-@{i} { margin-top: @i px; }❌ 语法错误,Less 不允许空格分隔数值与单位
递归混入不适合动态数据,仅适用于编译期已知结构
所有递归展开都在 Less 编译阶段完成,生成的是静态 CSS 规则。它不能响应运行时 JS 数据变化,也不能读取数组变量(Less 没有数组类型)。所谓“列表渲染”只是伪概念——你只能提前写死上限(如 @n: 20),或靠构建脚本注入参数。
如果实际需要根据后端返回的 class 名列表生成样式,应该:
• 改用 CSS-in-JS 方案(如 styled-components 的 css 函数)
• 或在构建流程中用 PostCSS 插件预处理 Less 源码
• 直接放弃 Less,切到 Sass(原生支持 @each)
递归混入真正的价值,是避免手写几十行重复规则;它的代价是可读性下降、调试困难,且一旦嵌套过深(比如生成 100 条规则),Less 编译速度会明显变慢。










