less 不支持原生循环语法,range() 和 for 是 sass 特性;其“循环”只能通过递归 mixin + when 守卫实现,否则会报错。

Less 没有循环函数,所谓“循环”全是靠递归 mixin + 守卫(when)模拟出来的;直接写 for、range() 或 each(1..12) 会编译失败。
为什么 Less 里不能用 range() 或 for 语法
Less 原生不支持数值区间迭代函数。你看到的 range(1, 12) 要么是别人封装的 mixin 名字(实际还是递归),要么是抄错的 Sass 语法。Less 编译器遇到它会直接报 ParseError: Syntax Error 或 ReferenceError: range is not defined。
常见错误包括:
- 把 Sass 的
@for $i from 1 through 12复制进 Less 文件 - 误以为
each()能遍历数字区间——它只能遍历已定义的列表(如@lists: 0, 4, 8, 12;) - 在递归 mixin 中漏写
when守卫,导致无限调用、卡死编译或爆栈(Maximum call stack size exceeded)
用递归 mixin 生成 mt-1 到 mt-8 这类工具类
核心是定义一个带计数参数、有终止条件、每次生成一类再调用自己的 mixin。注意三点:变量插值用 @{i},不是 @i;单位计算要括号包裹;终止条件必须显式写出。
示例(生成 rem 单位的 margin-top 工具类):
.make-mt-classes(@i: 8) when (@i > 0) {
.mt-@{i} {
margin-top: (@i * 0.25rem);
}
.make-mt-classes(@i - 1);
}
.make-mt-classes();
关键细节:
-
@i: 8是初始值,不能省略;否则@i未定义 -
when (@i > 0)是守卫,控制递归出口;换成when (@i >= 0)且没处理@i: 0场景,会导致生成.mt-0后继续调用.make-mt-classes(-1),无限下去 -
@{i}必须用插值语法,否则输出的是字面量.mt-@i,不是.mt-3 -
(@i * 0.25rem)的括号不能少——@i * 0.25rem可能被解析为@i*0.25rem,单位丢失
批量生成多方向、多数值的间距类(如 pt-8、mb-16)
别嵌套多层递归,容易超默认 256 层深度限制。更稳妥的做法是:先定义数值列表,再用单层递归遍历该列表,每轮生成全部方向。
示例(基于 @lists: 0, 4, 8, 12, 16, 24, 32;):
@lists: 0, 4, 8, 12, 16, 24, 32;
<p>.loop(@index) when (@index =</p><p>.pt-@{num} { padding-top: (@num <em> 1px); }
.pb-@{num} { padding-bottom: (@num </em> 1px); }
.ml-@{num} { margin-left: (@num <em> 1px); }
.mr-@{num} { margin-right: (@num </em> 1px); }</p><p>.loop(@index + 1);
}
.loop(1);</p>
要点:
-
extract(@lists, @index)从列表取值,索引从 1 开始(不是 0) - 所有单位统一用
* 1px,避免@num px导致0 px这种冗余写法 - 如果需要支持负值(如
mt--2),得额外加分支:when (@num ,不能只靠正向递归覆盖 - 想加
!important?直接写在声明末尾:padding-top: (@num * 1px) !important;
真正难的不是写对第一版,而是后续维护时改一个数值、加一个断点、支持新单位——这些都会让递归逻辑迅速变脆。建议数值列表单独抽离,守卫条件写死上限,别试图用变量动态算最大深度。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











