z-index只对定位元素生效,因position: static元素不参与层叠上下文排序;仅position: relative/absolute/fixed/sticky可启用z-index,且父元素触发层叠上下文(如opacity

z-index 只对定位元素生效,不是“bug”,是 CSS 层叠模型的硬性规则——没设 position(即保持 static),写 z-index: 9999 和写 z-index: 0 效果完全一样:浏览器直接忽略。
为什么 position: static 的元素无视 z-index
因为 z-index 的作用域只存在于“层叠上下文”中,而 position: static 元素既不创建新上下文,也不参与父级上下文内的 z-index 排序。它被当作普通文档流元素,按默认层叠顺序(background → border → inline content → …)渲染,z-index 根本没机会介入。
常见错误现象:
- 给一个
div直接加z-index: 100,但没改position,结果完全没变化 - 用浏览器开发者工具检查,发现 computed 样式里
z-index显示为auto(哪怕你写了数字)
哪些 position 值能真正启用 z-index
只有以下四种值能让 z-index 进入计算流程:
-
position: relative:最常用,不脱离文档流,适合仅需微调或作为子元素绝对定位的参考容器 -
position: absolute:脱离流,依赖最近的已定位祖先;必须确保父级有position: relative/absolute/fixed/sticky -
position: fixed:相对于视口固定,天然创建新层叠上下文(即使z-index: auto) -
position: sticky:滚动时在 relative 和 fixed 间切换,同样支持z-index
注意:position: static 是默认值,显式写出等于没写;position: inherit 或 unset 若最终计算为 static,z-index 依然无效。
z-index 生效但没按预期覆盖?大概率是层叠上下文隔开了
即使所有元素都加了 position 和 z-index,仍可能失效——因为父容器悄悄创建了独立的层叠上下文,把子元素“关进小房间”里比高低。
典型触发条件(父元素只要满足任一,就会隔离子元素的 z-index):
-
opacity小于1(如opacity: 0.99) -
transform不为none(如transform: translateZ(0.1px)、scale(1)) -
position非static且z-index为具体数值(哪怕只是z-index: 0) - 父元素是
flex或grid容器,且子项设置了z-index
后果:子元素 z-index: 999 再高,也盖不过外部 z-index: 2 但处于更高层叠上下文的导航栏。
调试时最容易被忽略的一点
浏览器开发者工具的“Computed”面板里看到 z-index 是数字,不代表它真在起作用——得看它所属的层叠上下文是否和目标元素一致。打开 Layers 面板(Chrome / Edge),或手动检查父级是否触发了新上下文(比如有没有 transform、opacity、will-change)。DOM 顺序仍是兜底规则:同级未设 z-index 的定位元素,后出现的永远压在先出现的上面。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











