遮罩层未盖住内容需依次检查:①是否遗漏position定位声明(z-index对static无效);②父容器是否创建新层叠上下文(transform/filter/opacity等);③弹窗与遮罩z-index是否分层合理(如遮罩3001、弹窗3000、下拉框3002);④Less中&后不可有空格,避免误生成后代选择器。

遮罩层没盖住内容?先确认 position 和 z-index 是否同时生效
z-index 对 position: static 元素完全无效,这是最常被忽略的前提。Less 里写了 z-index: 9999 却没起作用,大概率是因为漏了定位声明。
必须显式加 position: fixed(推荐)或 position: absolute,再配合四边归零:
.modal-overlay {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, 0.7);
z-index: 9999;
}
别用 width: 100%; height: 100% 替代四边归零——它依赖父容器尺寸,在 fixed 下行为不可靠。
遮罩被父容器“关在里面”?检查是否触发了新层叠上下文
即使 z-index: 9999 写得再高,只要遮罩的某个祖先元素有 transform、filter、opacity: 0.99 或 will-change,就会创建独立层叠上下文,让遮罩永远出不去。
立即学习“前端免费学习笔记(深入)”;
- 打开开发者工具 → 选中遮罩层 → 看 “Containing block” 是否显示为某个 div(而不是
(root)) - 临时删掉可疑父级的
transform: translateZ(0)或opacity: 0.99,观察是否恢复 - 若无法改父级样式,把遮罩节点挂到
body下(如用teleport或手动appendChild)
弹窗和遮罩层级打架?别盲目堆高 z-index
Element Plus 的 el-dialog 默认 z-index: 3000,遮罩设成 2000 就会被压;但设成 999999 又可能反向压住内部下拉框(如 el-select 的 .el-select-dropdown 默认 z-index: 2000)。
合理做法是分层控制:
-
.modal-overlay:设z-index: 3001(略高于弹窗本体) -
.el-dialog:保持默认或显式设z-index: 3000 -
.el-select-dropdown:全局补z-index: 3002 !important,确保浮在遮罩之上
所有涉及弹窗组件的 z-index 调整,必须进全局样式(如 App.vue 的 <style>),<style scoped> 无法穿透。
Less 嵌套写遮罩时,& 后多一个空格就失效
Less 中 & 是父选择器占位符,后面**不能有空格**,否则生成后代选择器,权重飙升且易被意外覆盖。
错误写法:.modal { & .overlay { z-index: 9999; } } → 编译为 .modal .overlay,权重 0-2-0,还可能被其他 .overlay 干扰。
正确写法:.modal { &__overlay { z-index: 9999; } } → 编译为 .modal__overlay,权重 0-1-0,物理隔离。
如果遮罩是独立组件(非嵌套在 .modal 内),直接写顶层类名,别为了“结构对应”硬套嵌套——Less 不是 HTML 结构快照工具。


















