Less不支持原生for、while循环,所谓“循环生成z-index”实为通过.each()或递归mixin配合守卫条件模拟实现。

Less里没有原生计数器循环,for不是关键字
Less不支持for、while这类运行时循环语法,所谓“循环生成z-index”本质是利用.each()或递归混合(mixin)+ 保护条件模拟。直接写for (let i = 0; i 会报错:<code>ParseError: Unrecognised input。
常见错误现象:复制粘贴Sass的@for写法,结果编译失败;或误以为each()能像JS一样遍历任意数组——其实Less的.each()只接受预定义列表(如@z-list: 1, 2, 3;),且不能动态构造。
- 必须提前定义好索引值列表,比如
@z-indices: 10, 20, 50, 100, 999; - 递归mixin需要显式终止条件,否则触发
Maximum call stack size exceeded - 生成的CSS规则顺序依赖调用顺序,
z-index叠加层逻辑容易和实际DOM结构脱节
用递归mixin安全生成连续z-index序列
这是最可控的方式:定义起始值、步长、总数,靠自身调用展开。关键在when守卫防止无限递归。
.z-stack(@i: 1, @step: 10, @total: 5) when (@i =< @total) {
.z-@{i} { z-index: (@i * @step); }
.z-stack((@i + 1), @step, @total);
}
.z-stack(); // 调用:生成 .z-1 ~ .z-5,z-index 分别为 10, 20, 30, 40, 50
注意参数命名要避开@index(Less内置变量,会覆盖);@step设为10比1更实用——避免无意中覆盖浏览器默认层叠上下文(如position: fixed元素默认约z-index: 100)。
立即学习“前端免费学习笔记(深入)”;
- 修改
@total即可控制生成数量,无需手动增删类名 - 所有生成类都带命名空间(如
.z-3),避免全局污染 - 若需跳过某些值(如避开
z-index: 2147483647这种危险值),得改用列表遍历而非纯数字递归
用.each()处理非连续z-index需求
当索引值不规则(如弹窗999、加载遮罩1000、全屏提示2147483647),硬套递归反而难维护。此时用.each()配合预定义列表更清晰:
@z-layers: tooltip 100, modal 999, overlay 1000, toast 1001;
.each(@z-layers, {
.z-@{value[0]} { z-index: @value[1]; }
});
这里@z-layers是二维列表,每项[name, value];@value[0]取类名前缀,@value[1]取数值。Less 4.0+才支持这种写法,旧版需降级为一维列表+额外映射逻辑。
- 语义明确:类名和用途强绑定(
.z-modal比.z-2可读性高得多) - 数值可任意设置,不受数学规律约束
- 列表顺序即CSS输出顺序,但不会影响层叠效果——最终生效取决于具体选择器权重和DOM位置
生成的z-index类怎么用才不翻车
动态生成只是第一步,真正踩坑多在使用环节。核心原则:不要让z-index成为“魔法数字”的替代品。
- 避免在组件内部直接写
.z-modal { z-index: 999; }——应通过父容器层级传递,比如.app-modal { z-index: var(--z-modal); }再配合CSS自定义属性 - Less生成的类只负责提供原子值,具体组合靠BEM或Utility类拼装,例如
<div class="modal z-modal"> <li>如果项目已用CSS-in-JS或Tailwind,Less生成的<code>z-类可能冗余,优先考虑运行时注入或@layer隔离
最易被忽略的一点:z-index生效前提是元素有定位(position值不为static)。Less生成再多类,没配position: relative照样无效。


















