z-index生效需同时满足两个条件:元素必须已定位(position为relative/absolute/fixed/sticky),且与目标元素处于同一堆叠上下文;若position为static或父级创建了新堆叠上下文(如opacity

z-index 不是写上就生效的“魔法数字”,它只在满足两个硬性条件时才参与层级计算:元素必须已定位(position 值为 relative、absolute、fixed 或 sticky),且必须和目标元素处于**同一个堆叠上下文(stacking context)**。数值大小只在同一上下文中起作用,跨上下文时完全无效。
为什么写了 z-index 却没效果?
最常见原因就是漏了 position —— 元素仍是 static(默认值),此时浏览器直接忽略 z-index。
- 检查开发者工具「Computed」面板,确认
position最终值不是static,且z-index显示为具体数字(而非auto) - 框架组件(如 Vue 的
v-if或 React 的内联样式)可能覆盖你写的position,导致失效 -
flex或grid子项即使视觉上“浮动”,也仍需显式加position才能启用z-index - 不要用
position: absolute布局整页,容易意外触发父级堆叠上下文,让后续层级调试失控
为什么 z-index: 999 还是被 z-index: 1 盖住?
问题不在数字本身,而在它们分属不同堆叠上下文。父容器一旦创建了新上下文,子元素的 z-index 就只在内部比大小,无法“越级”影响外部。
- 触发新堆叠上下文的常见操作:
position: relative+z-index(非auto)、opacity: 0.99、transform: translateZ(0)、will-change: transform - iOS Safari 对
transform和will-change极其敏感,哪怕只为硬件加速,也可能意外创建上下文 - 排查方法:DevTools 中搜索 “Stacking Context”;临时注释掉父级的
opacity或transform,看层级是否恢复 - 不要盲目堆高数值(如
z-index: 999999),先理清 DOM 嵌套链上谁悄悄当了“小 boss”
z-index 相同或未设置时谁在上面?
同一堆叠上下文中,z-index 相同或都为 auto 的定位元素,渲染顺序按 HTML 出现先后:DOM 中靠后的那个显示在前面。
-
z-index: auto和未设z-index的定位元素,归入同一层(stack level 0) - 负值(如
z-index: -1)会让元素沉到背景层下面,可能被父容器边框或背景盖住 - 非定位元素(
static)永远排在定位元素之下,无论 HTML 顺序如何 - iframe 是完全独立文档环境,它的
z-index与父页面无任何关系;想遮盖它,只能在同级 DOM 插入遮罩,并确保该遮罩的父容器有更高堆叠优先级
真正难调的不是数值本身,而是搞清当前元素嵌在哪几层上下文中——浏览器 DevTools 的「Layers」面板或「Computed」里的 stacking context 提示,比硬猜靠谱得多。最容易被忽略的,是以为在调整个别按钮的层级,其实是在调试整棵上下文嵌套链。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











