z-index不生效的根本原因是元素未进入层叠上下文;必须设置position为relative/absolute/fixed/sticky等非static值才能触发,且父子层叠上下文会限制z-index作用范围。

z-index 不生效?先确认元素有没有定位
绝大多数 z-index 失效,根本原因不是值写错了,而是元素压根没进入「层叠上下文」——而触发层叠上下文最常见的方式,就是给元素加 position(除 static 外的任意值)。
比如:div { z-index: 10; } 完全无效,因为默认 position: static;必须改成 position: relative; 或 absolute 等才起作用。
-
position: static:z-index被忽略,无论设多少都无效 -
position: relative / absolute / fixed / sticky:z-index开始参与层叠计算 - 父元素有
transform、filter、opacity < 1等也会隐式创建层叠上下文,影响子元素z-index的作用范围
为什么两个同级元素设了不同 z-index 还是叠反了?
层叠顺序不是只看 z-index 数字大小,而是按「层叠上下文 + 层叠等级」逐级比较。如果两个元素不在同一个层叠上下文中,它们的 z-index 根本不直接比。
典型场景:父容器 A 设了 z-index: 1,内部子元素 A1 设 z-index: 999;另一父容器 B 设 z-index: 2,内部子元素 B1 设 z-index: -1。结果一定是 B 整体盖在 A 上面——A1 再高也出不了 A 的层叠上下文边界。
立即学习“前端免费学习笔记(深入)”;
- 每个层叠上下文内部自成一套
z-index体系,只跟父上下文的层叠等级挂钩 - 父元素的
z-index值决定了整个子树在外部的“高度”,子元素再大也突破不了这个上限 - 用浏览器开发者工具的「Layers」面板(Chrome)或「Computed」里的
z-index和stacking context可直观验证是否被截断
z-index 用负数安全吗?什么情况下会掉到背景下面
负 z-index 是合法的,但非常容易踩坑:它会让元素沉到其所在层叠上下文的「背景和边框之下」,甚至可能被父容器的背景盖住,而不是单纯被兄弟元素遮挡。
比如一个 position: relative 的卡片内,按钮设 z-index: -1,结果按钮直接看不见了——不是被别的按钮挡住,而是掉到卡片自己的 background-color 底下了。
- 负值只建议用于需要「嵌入父容器内容层之下」的极少数场景(如自定义滚动条轨道)
- 绝对定位元素设负
z-index时,若父元素没创建新层叠上下文,它会尝试沉到<html>或最近层叠上下文的底层,行为难预测 - 更稳妥的做法是统一用正数,并通过调整父级
z-index控制整体层级关系
Flex/Grid 容器里的子项能用 z-index 吗?
可以,但前提是子项本身有定位(position 非 static)。Flex 和 Grid 本身不自动创建层叠上下文,也不阻止 z-index 生效。
不过要注意:Flex/Grid 的顺序(order)、文档流顺序、以及是否启用 z-index 是三套独立机制。别指望改 order: 2 就能替代 z-index 控制覆盖关系。
- 子项没设
position:即使z-index写了也无效 - 子项设了
position: relative+z-index:正常参与层叠,且不受order影响 - Grid 中使用
z-index时,注意grid-area重叠区域内的渲染顺序仍由层叠规则决定,不是网格定义顺序










