z-index“选不中”主因是未进入同一层叠上下文:元素未定位、父级创建新上下文(如opacity/transform)、或DOM路径上存在隔离属性;须检查position声明与堆叠上下文层级。

z-index“选不中”,不是值写小了,而是你根本没进对那个层叠上下文——元素没定位、父级悄悄建了隔离盒子、或者你调的z-index压根不在同一个比较域里。
元素没设 position,z-index 就是废代码
浏览器对 z-index 的处理非常干脆:只要 position 是 static(默认值),就直接跳过该声明,连警告都不报。你在 DevTools 里看到它灰显、Computed 面板显示 auto,就是这个信号。
- 动态插入的弹窗、Tooltip 或 JS 创建的浮层,最容易漏掉
position: fixed或position: absolute - Vue/React 中用 class 切换样式时,若新 class 没带定位声明,旧规则被覆盖后
position就退回static -
display: flex或grid容器里的子项,不能靠布局模式“自动获得”定位能力;z-index要生效,仍需自己声明position: relative(最安全,不影响流式布局)
父级用了 opacity/transform/filter,子元素 z-index 就“出不去”
这些属性看着只是视觉微调,但只要偏离默认值,就会强制创建新的层叠上下文(stacking context)。一旦触发,子元素的 z-index 只能在它内部比大小,跟同级其他组件完全无关。
- 常见“静默触发者”:
opacity: 0.99、transform: translateZ(0)、filter: blur(0)、will-change: transform、isolation: isolate - 在 Chrome DevTools 的 Elements 面板中逐级点击父节点,右侧面板 Layout 标签页下看「Stacking context」是否突然变成
Yes;重点盯那些没写z-index却显示Yes的节点 - 临时验证最快方式:注释掉父级的
transform或opacity,遮挡立刻消失,就说明找对了“结界”
BEM 块必须自己创建上下文,别指望子元素扛事
像 .modal 这类 BEM 块,默认是 position: static,z-index 完全无效。更危险的是:只给 .modal__overlay 设 z-index,却不给 .modal 根元素加 position——子元素的层级声明会被浏览器无视。
立即学习“前端免费学习笔记(深入)”;
-
.modal必须显式设position: fixed(全屏遮罩)或position: relative(挂载点需保留在文档流内) - 禁止在 Modifier 类(如
.modal--fullscreen)里覆盖z-index;层级属于 Block 职责,Modifier 只管颜色、尺寸等视觉属性 - 语义化变量管理:
--z-modal、--z-dropdown、--z-toast分开定义,避免写死在:root;子元素用calc(var(--z-modal) - 1)做相对偏移
真正卡住你的,往往不是数字写多少,而是 DOM 路径上某一层的 transform 或 opacity 悄悄把你关进了独立盒子——得往上翻三五层,而不是往下堆 z-index: 9999。


















