z-index必须用变量声明且统一管理,禁用魔法数字;@import须严格分层并避免重复引入;父级触发层叠上下文会导致子元素z-index失效;CSS自定义属性需显式赋值才参与层叠计算。

z-index必须用变量声明,不能直接写数字
Less里写z-index: 999看似能跑通,但项目一上规模就崩:Modal盖不住Dropdown、Toast被Header吞掉,根源就是散落各处的魔法数字。编译后它们互不感知,谁先输出谁赢。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 新建
variables.less,统一定义@z-toast: 300;、@z-dropdown: 500;、@z-modal: 900; - 相邻层级至少差10,比如
@z-tooltip: 300;和@z-modal: 900;之间留出插入空间 - 变量名必须绑定UI角色,禁用
@z-high这种模糊词——没人知道它该不该压过position: sticky的表格头 - 禁止跨模块复用同名变量,Button的
@z-focus-ring和Modal的@z-focus-ring必须是两个变量,哪怕值相同
@import顺序决定层叠上下文的“出场顺序”
Less所有@import在编译期被提升到顶部、按书写顺序拼接。这意味着@import "components/button.less";写在@import "base/reset.less";前面,按钮样式就会先出现,重置规则后压上去,结果按钮边框和内距全没了。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 入口文件(如
index.less)头部集中写@import,严格按「重置 → 变量/mixin → 基础组件 → 业务组件 → 页面定制」分层 - 禁止在
button.less里再@import "mixins.less"——依赖关系失控,样式块可能插进不该在的位置 - 用
@import (reference)引入只提供变量和mixin的文件,避免重复输出CSS - 别靠文件名排序(比如
_01-base.less),Less根本不识别这种命名
父级触发层叠上下文,子元素z-index就“锁死”了
写了z-index: @z-modal却还是被盖住?大概率是父容器悄悄加了transform、opacity: 0.99或will-change,创建了新层叠上下文,把你整个子树关在里面比大小。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- Chrome DevTools打开「Layers」面板,直接看层叠上下文边界
- 逐级检查父节点是否带
transform: translateZ(0)、filter: blur(0)等隐式触发属性 - 临时注释掉父级
transform或opacity,看遮挡是否立刻消失——这是最快定位手段 - 需要动态提层时,把
z-index设在触发层叠上下文的那层,而不是只设在最内层元素上
导出CSS自定义属性时,z-index不能只靠@value替换
想用JS读取层级?别直接把Less变量转成--z-modal: 900就完事。CSS自定义属性只是字符串容器,不参与层叠计算,你得手动再赋值一次。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- Less中仍用变量控制逻辑,但最终输出必须显式写进规则:
.modal { z-index: var(--z-modal); } - 确保
:root里已定义--z-modal,且值与Less变量同步(可用@plugin或构建脚本自动注入) - 避免在嵌套规则里重定义
@z-modal——它只在当前作用域生效,容易误以为改了全局
position是否生效、父级是否意外建了新上下文、变量是否被局部覆盖——这三处漏掉任何一项,调试就变成碰运气。


















