z-index不生效的根本原因是层叠上下文被意外创建,导致子元素z-index仅在局部上下文中比较;常见触发条件包括opacity

z-index 不生效,不是数值太小,而是元素压根不在同一个比较场里。 层级错乱的根源几乎都出在层叠上下文(stacking context)被意外创建,而不是 CSS 写错了位置或 z-index 值不够大。
为什么加了 z-index 还是被盖住
浏览器只会在同一层叠上下文中比较 z-index。一旦某个父元素触发了新层叠上下文,它下面所有子元素的 z-index 就只能在它内部比大小,和外部完全无关。
- 常见触发条件:
opacity小于 1(哪怕opacity: 0.99)、transform非none(包括translateZ(0))、filter、will-change、isolation: isolate,还有position+z-index组合(哪怕z-index: 0) - 用 Chrome DevTools 选中目标元素 →「Computed」面板搜索
stacking context,标为 “Yes” 就说明它已进入新上下文 - 逐级向上检查父元素的
opacity、transform、filter等值;临时加opacity: 1 !important或transform: none !important观察是否恢复
position: absolute 元素突然飞到左上角
这不是 top 和 left 写错了,而是它没找到定位参考系——position: absolute 会向上查找**最近的非 static 定位祖先**作为包含块(containing block)。全都是默认 position: static,就直接相对于 viewport 定位。
- DevTools 中选中该元素 →「Computed」面板找
Containing block字段,看它实际绑定的是哪个节点 - 在 Elements 面板里从父节点开始逐级点开,确认是否有节点设置了
position: relative、absolute或fixed - 若预期父容器没设定位,就给它加
position: relative(无需偏移值),让它成为合法锚点
iOS Safari 中 z-index + transform 组合失效
iOS Safari 对 transform 和 z-index 的配合极其敏感:只要父容器用了 transform(哪怕只是 translateZ(0)),又没显式声明 z-index,其子元素即使设了 z-index,也可能被错误渲染。
- 稳妥解法:在触发
transform的父容器上,**同时加position: relative和z-index: 0** - 避免只靠
transform: translateZ(0)强制硬件加速却不设z-index - 测试必须用真机,模拟器常无法复现该问题
真正难排查的,往往是某一层父容器悄悄加了 opacity: 0.99 或 will-change: transform,既不报错也不高亮,却把整个子树的层级逻辑锁死在局部。别急着调 z-index 数值,先查 stacking context。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











