z-index在CSS Grid中失效的根本原因是子项未定位或父容器意外创建层叠上下文;必须为grid-item显式设置position(如relative)并确保父容器未触发opacity、transform等隔离行为。

z-index 在 CSS Grid 中“表现不同”,根本不是 Grid 本身改了规则,而是你更容易踩进两个经典陷阱:**子项没定位**,或**父容器意外创建了层叠上下文**。只要这两个条件满足,Grid 里的 z-index 行为和普通 div 完全一致。
grid-item 的 z-index 没反应?先检查 position
Grid 子项默认是 position: static,而 z-index 对 static 元素完全无效——这不是 Grid 特性,是 CSS 规范铁律。
-
grid-item { z-index: 10; }→ 无效,z-index被浏览器忽略 -
grid-item { position: relative; z-index: 10; }→ 生效,且不改变 Grid 布局位置 - 避免用
position: absolute来“调层级”:它会让元素脱离 Grid 轨道,同时脱离容器的层叠上下文,z-index开始跟body或最近定位祖先比,而不是兄弟grid-item
多个 grid-item 重叠时,谁在上?
当多个 grid-item 占据同一网格区域(比如都设了 grid-area: header),它们的绘制顺序由两层逻辑共同决定:
- 如果都没设
z-index:按 HTML 源码顺序,后写的那个自然盖在前面的上面 - 如果都设了
z-index:数值大的在上,不管 DOM 顺序 ——z-index: 2一定压过z-index: 1 -
z-index: 0和不写z-index效果不同:前者进入层叠比较,后者走源码 fallback
为什么加了 z-index 还被隔壁模块盖住?
大概率是某个父容器(可能是 Grid 容器自己,也可能是它的祖先)触发了新的层叠上下文,把你的 grid-item “关进小房间”里比高低了。
- 触发条件包括:
transform: translateZ(0)、opacity: 0.99、filter: blur(0)、will-change: transform、甚至isolation: isolate - Chrome DevTools 的 Layers 面板能直接看到哪些元素成了层叠上下文边界
- 临时验证:注释掉可疑父级的
transform或opacity,如果遮挡消失,问题就定位准了 - 长期解法:给那个触发上下文的父容器本身加
position: relative+ 合理z-index(比如z-index: 100),而不是只给子项狂堆9999
Grid 容器设了 z-index 有用吗?
有用,但只影响它和兄弟元素的关系,不影响内部子项之间的层级排序。
-
.grid-container { position: relative; z-index: 5; }→ 它会在兄弟元素中排第 5 层 - 但它内部的
grid-item的z-index仍按全局规则参与比较(除非容器自身也成了层叠上下文) - 想让子项的
z-index只在容器内生效?加isolation: isolate,但这会切断与外部的层级联系,慎用
真正容易被忽略的点是:**Grid 天然支持多元素占据同一区域,而开发者常以为“写了 grid-area 就自动获得层叠资格”,其实没有——必须手动激活定位,才能让 z-index 开始工作。**
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











