必须用 Sass 变量统一管理 z-index,否则将引发弹窗被遮盖、下拉菜单消失等线上事故;需命名变量(如$z-modal-overlay: 1000)、严格递增留间隙、按职责分区,并通过@use显式引入+命名空间调用,避免作用域断链与混用 CSS 变量。

必须用 Sass 变量统一管理 z-index,不是为了“优雅”,而是防止弹窗被遮盖、下拉菜单消失、Toast 突然沉底这类线上事故——手写 z-index: 999 的那一刻,就已经埋下不可调试的隐患。
为什么直接写数字是高危操作
它看起来快,但会立刻引入三类问题:
- 数值无语义:
z-index: 1200是 toast 还是 modal 遮罩?没人能靠数字猜出来 - 易冲突:A 模块和 B 模块都写了
z-index: 1000,但因父容器 stacking context 不同,B 被压在下面,现场难复现 - 难维护:删一个组件时不敢动它的
z-index,加新组件时得全局grep "z-index"找“下一个可用值”,稍有遗漏就出事
怎么定义真正可读、可扩展的 Sass 变量
核心是显式声明层级意图,而不是靠顺序或魔法数字。推荐结构如下:
- 用命名变量,不用裸数字:
$z-modal-overlay: 1000,而非$z-1000——IDE 能跳转,拼错会编译报错 - 值必须严格递增且留间隙:
$z-tooltip: 700、$z-dropdown: 900、$z-modal-overlay: 1000,中间空出 99 的余量,方便后续插入$z-combo-box: 950 - 按职责分区,不跨区越界:基础层(
$z-background: -10)、浮层层($z-toast: 990)、强弹窗层($z-modal-content: 1010) - 禁用
$z-max或$z-9999类别名——它违背语义,且与 Headless UI 等库默认值冲突
常见错误:变量写了却没生效
最典型的情况不是语法错,而是作用域断链:
立即学习“前端免费学习笔记(深入)”;
- 忘了
@use "path/to/z-index" as z,导致变量未注入;调用时写成z-index: $z-modal而非z-index: z.$z-modal - 组件中写了
z-index: $z-modal,但该文件根本没@use变量模块 - 混用 Sass 变量和 CSS 自定义属性:
z-index: $z-modal和z-index: var(--z-modal)同时存在,造成维护断层 - 检查编译后 CSS:如果输出的是
z-index: $z-modal(原样未替换),说明变量未解析,大概率是路径错误或未@use
JS 动态提层时必须同步 CSS 变量
Sass 变量编译后就消失了,JS 无法读取。若 Modal 组件需 hover 时下拉菜单上浮,或主题切换时降级层级,就必须导出为 CSS 自定义属性:
- 在
_variables.scss中定义后,加一句::root { --z-modal: #{$z-modal-overlay}; } - CSS 中写:
z-index: var(--z-modal);,而非直接引用 Sass 变量 - JS 中通过
el.style.setProperty('--z-modal', '1050')动态调整,确保与 CSS 层级一致 - 禁止把所有变量塞进
:root全局;更稳妥的是按模块就近定义,如.dropdown { --z-dropdown: #{$z-dropdown}; }
复杂点在于:一旦用了 Portal 或动画触发新 stacking context,z-index 就不再是线性比较,而是树状嵌套——这时候再“优雅”的 Sass 映射表也救不了你,必须回到浏览器的 Layers 面板去验证真实渲染层结构。


















