z-index不起作用主因是元素未定位或被父层叠上下文隔离;需确保position非static,且检查祖先是否因opacity/transform/filter等创建了新层叠上下文。

z-index 不起作用,几乎从不因为数值写小了,而是元素根本没进入层叠计算流程——要么没定位,要么被父级层叠上下文“锁住”了。
为什么加了 z-index 还是被盖住?先看 position 有没有生效
最常见也最容易忽略的问题:z-index 只对非 static 定位的元素起作用。默认 position: static 下,浏览器直接无视 z-index 声明,连控制台警告都没有。
- 用 Chrome DevTools 的 «Computed» 面板检查目标元素,搜
position,确认它不是static - 临时加一句
position: relative(几乎不影响布局),立刻验证是否恢复层级控制 - JS 动态插入元素时,容易只设
z-index却漏掉position;Vue/React 中 class 切换后,也要防其他样式规则把position覆盖掉 -
display: flex或grid的子项虽可响应z-index,但前提是它自己已定位(position非static)——不能依赖父容器的定位属性“继承”过来
父元素悄悄创建了层叠上下文,子元素的 z-index 就“作废”了
只要某个祖先元素满足以下任一条件,它就创建了新的层叠上下文(stacking context),子元素的 z-index 只能在它内部比大小,无法和外部同级元素竞争:
-
opacity小于 1(哪怕opacity: 0.999) -
transform不为none(包括看似无害的transform: translateZ(0)、scale(1)) -
filter不为none(哪怕filter: blur(0)) -
will-change: transform或will-change: opacity isolation: isolate-
position: fixed或sticky且z-index非auto
实操建议:
- 在 Chrome DevTools 的 Elements 面板中逐级点击父节点,右侧面板 «Layout» 标签页里留意 «Stacking context» 是否突然变成 Yes
- 临时注释掉父级的
transform或opacity,看遮挡是否立刻消失——这是最快定位手段 - 别只修子元素,要么删掉父级触发上下文的属性,要么把需要“突围”的元素(如
dropdown、tooltip)用position: fixed挂到body下(记得手动处理滚动偏移)
z-index: 0 和 z-index: auto 看似一样,实际效果截然不同
很多人以为加个 z-index: 0 很安全,其实它会强制创建新层叠上下文;而 z-index: auto(默认值)不会(前提是元素已定位)。这个细节常导致“明明啥都没动,突然就盖不住了”。
- 检查父容器是否意外设置了
position: relative+z-index: 0,这等于主动建了个结界 - 如果只是想让元素参与层叠排序但不想隔离上下文,用
z-index: auto更稳妥 -
z-index: -1会让元素沉到父上下文的背景和边框之下,慎用
真正难的不是堆数字,而是看清谁在哪个盒子里比大小。一旦有 transform、opacity 或 filter 出现在 DOM 路径上,就得停下来问一句:这个“盒子”,是不是我真想让它管住所有子元素?
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











