z-index仅对position为relative、absolute、fixed或sticky的元素生效;静态定位下完全被忽略;需注意堆叠上下文限制及Flex/Grid中子项须显式定位才支持z-index。

z-index 不生效?先确认元素是不是定位元素
z-index 只对 position 值为 relative、absolute、fixed 或 sticky 的元素起作用。静态定位(position: static,也就是默认值)下设 z-index 完全被忽略——浏览器连解析都不解析。
- 常见错误现象:
z-index: 999写了但图层顺序没变,检查 computed style 会发现position还是static - 实操建议:哪怕只是想“让这个 div 浮在上面”,也得加一句
position: relative,不占布局位置又最安全 - 注意:
position: sticky的z-index行为和relative类似,但受父容器滚动边界影响,容易误判堆叠上下文
子元素 z-index 被父容器截断?理解堆叠上下文
一个设置了 z-index 且 position 非 static 的元素,如果同时满足某些条件(比如有 opacity < 1、transform、filter 等),就会创建新的堆叠上下文。它的子元素的 z-index 只在这个上下文内比较,不会跑到父级上下文外面去。
- 典型场景:弹窗里有个带
transform: scale(0.95)的卡片,卡片里的按钮设了z-index: 9999,结果还是被弹窗外的导航栏盖住 - 原因不是 z-index 数值小,而是弹窗父容器因
transform创建了新堆叠上下文,按钮的层级再高也出不去 - 排查方法:在 DevTools 的 Layers 面板里看是否多了一层 “Stacking Context”;或者临时移除父元素的
transform/opacity等属性验证
z-index 数值该设多大?别迷信 9999
z-index 是整数,支持负值(-1 很常用),没有“最大安全值”。设成 999999 不如搞清结构层级关系,否则后期维护时谁都不敢动这个数字。
- 推荐做法:按组件职责分层,比如
z-header: 100、z-modal: 1000、z-tooltip: 2000,留足间隙方便插入中间层 - 负值有用:比如
z-index: -1可以让装饰性背景图严格沉底,又不用改 HTML 结构 - 注意兼容性:IE6/7 对
z-index解析有 bug,会把非定位祖先元素也当作堆叠上下文起点,不过现在基本可忽略
Flex/Grid 容器里的子项重叠,z-index 还管用吗?
管用,但前提是子项本身是定位元素。Flex 和 Grid 项目默认是 position: static,直接写 z-index 没反应。
立即学习“前端免费学习笔记(深入)”;
- 常见错误:给
display: flex的容器里两个div分别设z-index: 1和z-index: 2,结果顺序没变 - 正确做法:给这两个子项加上
position: relative(或其他定位值),再设z-index - 补充说明:Grid 中的
z-index行为和 Flex 一致;但若用了grid-area重叠,视觉上重叠 ≠ 层叠顺序混乱,此时z-index才真正介入控制绘制顺序
堆叠顺序不是靠堆数字解决的,而是靠理解定位、堆叠上下文和渲染流之间的咬合关系。最常被忽略的是:哪怕只加一行 position: relative,也可能意外创建新的堆叠上下文,从而锁死整个子树的层级自由度。










