z-index没生效主因是元素未定位或父级创建堆叠上下文;必须设position为relative/absolute/fixed/sticky才激活,且opacity

z-index 没生效,几乎从不因为数值写小了,而是它根本没被浏览器计算——要么元素没定位,要么被父级“结界”关在独立堆叠上下文里。
元素的 position 不是 relative/absolute/fixed/sticky
这是最基础也最高频的失效原因:z-index 对 position: static(默认值)完全无效,连 warning 都不报。
- 用 Chrome DevTools 的 «Computed» 面板检查该元素,确认
position最终值不是static - 临时加一句
position: relative(不影响文档流),立刻验证是否恢复层级控制 - Vue/React 中动态插入浮层(如 tooltip、modal)时,容易漏掉
position声明;class 切换后也可能被其他样式覆盖回static
父元素悄悄创建了堆叠上下文(Stacking Context)
只要某个祖先元素满足以下任一条件,它就创建了新堆叠上下文,子元素的 z-index 只在它内部起作用,无法和外部兄弟元素竞争:
-
opacity小于 1(哪怕opacity: 0.999) -
transform不为none(包括transform: translateZ(0)、scale(1)、rotate(0.0001deg)) -
filter不为none(哪怕filter: blur(0)或filter: opacity(1)) -
will-change: transform或will-change: opacity isolation: isolate-
position: fixed或sticky且z-index不是auto
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 在 Elements 面板中逐级点击父节点,右侧面板 «Layout» 标签页看 «Stacking context» 是否突然变成
Yes - 临时注释掉父级的
transform或opacity,遮挡立刻消失——这就是实锤 - 别只修子元素:要么删掉触发属性,要么给那个父容器自身设高
z-index(比如z-index: 105),让它整体抬高
z-index: 0 和 z-index: auto 的语义陷阱
很多人以为加个 z-index: 0 很安全,其实它会强制创建新堆叠上下文——而 z-index: auto(默认)不会(前提是元素已定位)。
- 检查父容器是否意外设置了
z-index: 0+position: relative,这等于主动建了个“结界” - 如果只是想让元素参与层叠排序但不想隔离上下文,用
z-index: auto更稳妥 - 负值如
z-index: -1会让元素沉到父上下文的背景和边框之下,慎用
真正难处理的不是“怎么调高”,而是识别哪个父级在静默创建上下文——尤其当它来自第三方组件、Tailwind 的 utility class,或 JS 动态注入的样式时,Stacking context: Yes 这个提示常被忽略。一旦漏掉这一层,所有后续调参都是徒劳。


















