z-index 只对非 static 定位元素生效,因其需参与层叠上下文排序;flex/grid 子项可例外使用 z-index 是因容器隐式创建层叠上下文;失效主因是父级触发新层叠上下文隔离了子元素的 z-index 作用范围。

z-index 为什么只对 position: relative/absolute/fixed/sticky 生效
因为 z-index 的本质不是“调高一个元素”,而是参与层叠上下文(stacking context)的排序——而只有非 static 定位的元素才能创建或加入一个有效的层叠上下文。
浏览器默认把所有 position: static 元素放在同一个“基础层叠上下文”里,且不接受 z-index 干预;一旦你设成 relative、absolute 等,它就脱离了静态流,获得独立参与排序的资格。
常见错误现象:
- 给普通
<div> 直接写 <code>z-index: 999,毫无反应 - 开发者工具里看到
z-index值显示为灰色带删除线,说明被忽略 - 不要依赖 flex/grid 的这个特性来绕过定位——它只适用于直接子项,嵌套一层就失效
- 若需跨层级控制堆叠,仍应显式设置
position: relative等,保证行为可预测 - 检查父容器是否用了
display: flex或display: grid,再判断子项z-index是否本该生效 -
opacity: 0.99(注意:opacity: 1不触发) -
transform: translateZ(0)或任何transform值 filter: blur(1px)will-change: transformisolation: isolate- 目标元素是否写了
position,且值不是static(哪怕只写position: relative什么都不动也行) - 它的任意祖先元素是否设置了上述层叠上下文触发属性(尤其是
opacity 或 <code>transform) - 它和要覆盖的目标元素是否处于同一层叠上下文——如果不是,再大的
z-index也越不过那道“门”
flex 或 grid 子项为什么没定位也能用 z-index
这不是 z-index “破例”,而是 flex 容器和 grid 容器本身会为子项隐式创建层叠上下文,让子项即使保持 position: static,也具备了参与层叠排序的前提条件。
但注意:这种行为是布局模型的副作用,不是通用规则。不能因此推导出“所有 static 元素都能用 z-index”。
实操建议:
为什么加了 position 还没效果?层叠上下文在“关小门”
即使目标元素已设 position: absolute 和 z-index: 9999,也可能被父级“锁死”在低层——只要父元素触发了新层叠上下文,子元素的 z-index 就只能在那个小范围里比大小。
典型触发父级新建层叠上下文的 CSS 属性:
调试时打开开发者工具,选中父元素,看“Computed”面板里是否出现 “Stacking Context” 提示——有,就说明子元素的 z-index 已被隔离。
z-index 失效时最该先查的三件事
别急着改数值,先确认基础前提是否满足:
真正麻烦的从来不是数值大小,而是上下文边界在哪里。看清这层关系,比盲目堆 z-index: 999999 有用得多。











