




z-index仅对position为relative、absolute、fixed或sticky的元素生效;若父元素创建了层叠上下文(如非static+非auto z-index),子元素z-index仅在该上下文中比较,无法超越父级影响外部层级。
最常见的情况是给一个普通 div 直接写 z-index: 999,但没加 position,结果完全没反应。CSS 规范明确规定:z-index 仅在元素的 position 值为 relative、absolute、fixed 或 sticky 时才有效。
position: static(默认值) → z-index 被忽略position: relative 且无偏移 → 层级生效,但视觉位置不变position: absolute 和 fixed 同时触发定位与层叠上下文创建,影响更广即使子元素设置了很高的 z-index,如果它的某个祖先元素满足以下任一条件,就会形成独立的层叠上下文(stacking context),导致子元素的 z-index 只在这个小圈子内比较,无法越过父级去和外部兄弟元素争高低:
position 非 static + z-index 为具体数值(非 auto)opacity 小于 1(如 opacity: 0.99)transform 不为 none(如 transform: translateZ(0))will-change 指定了影响层叠的属性filter、perspective、isolation: isolate 等典型表现:弹窗 .modal 内部按钮层级正常,但整个弹窗被页面顶部导航栏盖住——大概率是导航栏父容器触发了层叠上下文,且其 z-index 高于弹窗容器本身。
很多人以为“只要我写 z-index: 9999 就一定最大”,其实不是。两个元素是否能直接比大小,取决于它们是否属于同一个层叠上下文。
立即学习“前端免费学习笔记(深入)”;
z-index: 100
z-index: 10;B 自身设 z-index: 9999
z-index: 10 z-index: 100,B 再高也出不去 P 的边界调试建议:用浏览器开发者工具逐级检查「Computed」面板里的 stacking context 提示,或看 z-index 是否显示为灰色(表示被忽略)。
Flex 或 Grid 容器本身不会自动创建层叠上下文,但其子项(flex item / grid item)若设置了 position,z-index 依然生效。不过要注意一个易错点:
z-index 无效position: absolute),则相对于最近的定位祖先定
position: relative(哪怕不偏移),再配 z-index
.container {
display: flex;
}
.item {
position: relative; /* 必须加 */
z-index: 2;
}真正卡住人的往往不是 z-index 本身,而是它背后那套隐式、嵌套、依赖祖先状态的层叠规则。调的时候别只盯着目标元素,得顺着 DOM 往上翻两层,看有没有谁悄悄建了个“结界”。