z-index 为什么有时不生效?层叠上下文是怎么决定遮挡顺序的?
🧑💻 面试官:z-index 设置到 999999,为什么弹窗还在导航栏下面?
🙋♂️ 我:可能是弹窗没有设置 position。
🧑💻 面试官:弹窗是 position: fixed,父容器还有 transform。现在呢?
🙋♂️ 我:那我再把 z-index 增大一些?
🧑💻 面试官:如果父容器和导航栏处在不同的层叠上下文里,子元素的数值能越过父级吗?
z-index 不是全页面的统一排名;先找到层叠上下文,再比较同一层的顺序。
面试速答(60 秒版)
z-index 要放在层叠上下文里理解。同一上下文中的元素按相应绘制规则比较,子上下文作为整体参与父级排序,内部子元素不能靠更大的 z-index 越过这个整体的层级。
例如弹窗在 z-index: 1 的父上下文里,导航栏处于同级 z-index: 2 的上下文。弹窗内部即使是 999999,也可能仍在导航栏下面。
排查时我会沿祖先找 position 与 z-index、transform、opacity 等建立上下文的条件,再检查 overflow 裁剪。修复可以是调整正确的父级层级,或把弹层挂到合适的根容器;必要时使用浏览器 top layer,而不是继续堆数值。

知识点详解:先找到排序的层,再比较数字
把 999999 放回它所在的上下文
假设页面有两个兄弟区域:内容区建立层叠上下文,z-index 为 1;导航栏也建立层叠上下文,z-index 为 2。弹窗放在内容区里面,自己的 z-index 为 999999。
浏览器在它们共同的父上下文中比较时,先比较的是内容区与导航栏这两个整体。内容区排在导航栏下面,里面的弹窗也就一起在下面。弹窗的巨大数值,只能帮助它在内容区内部排序。
可以把它理解成先比较目录,再比较目录里的条目,但不要把这个比喻当成浏览器真的在计算“1.999999”这样的数值。关键是 上下文内部排序完成以后,会作为整体参与外部排序。
哪些设置会悄悄建立新上下文?
常见条件包括:定位元素配合非 auto 的 z-index;fixed 或 sticky 元素;opacity 小于 1;非 none 的 transform;以及 isolation: isolate 等。Flex 和 Grid 子项使用非 auto 的 z-index 也可以建立上下文。
所以,“z-index 必须配合 position 才有效”也不够准确,它遗漏了 Flex/Grid 子项等情况。
这里需要分清层叠上下文、包含块和合成层。它们可能被某些相同属性影响,但不是同一个概念。给祖先加 transform,除了改变层叠关系,还可能让 fixed 元素相对这个祖先定位;不能看到 GPU 图层就认为 z-index 问题已经解决。
遮挡和裁剪,要分开排查
弹窗看不见,还有一种可能:它不是排在别的元素下面,而是被祖先 overflow 裁剪了。增大层级不能让它自动逃出所有裁剪关系。
因此可以按这个顺序检查:先确认元素有没有渲染、尺寸与位置是否正确;再找遮住它的元素和共同上下文;最后检查祖先的 overflow、clip-path 等。
开发者工具里暂时取消一个 transform 或 overflow,很适合用来定位原因,但不能把“删掉一个属性后正常”直接当成最终方案。这个属性可能承担动画、滚动或布局职责。
弹层应该放在哪儿?
如果弹窗要覆盖整个页面,把它通过框架 Portal 或 Teleport 挂到统一的弹层根容器,通常比放在局部卡片内部更好管理。这里讨论放置原则,React Portal 和 Vue Teleport 各有自己的实现,不存在通用 Python 浏览器 API。
不过,换了 DOM 放置位置,还要检查焦点、滚动锁定和无障碍关系。弹窗能盖住导航栏,只说明视觉层级修好了,不代表交互已经完整。
原生 dialog 的模态显示、Popover 等机制可以进入浏览器 top layer。它不参与普通内容的同一套 z-index 排名,但仍要遵守对应 API 的生命周期和交互语义。
本题机制参考:MDN:Stacking context。

面试官继续追问
z-index 越大,浏览器越慢吗?
数值大本身不是主要性能问题。更值得检查的是复杂绘制、图层数量和动画方式;这里首先是排序和维护问题。
opacity: 0 会让元素不占空间吗?
不会。它仍可能占布局空间并参与交互。是否显示、是否占空间、是否响应事件,是不同问题。
Portal 能自动解决所有弹窗问题吗?
不能。它能改变 DOM 放置位置,避开部分祖先约束,但焦点管理、滚动、遮罩和层级约定仍要自己设计。
面试速记卡
- z-index:在对应层叠上下文中比较,不是全页面统一排名。
- 子上下文:作为整体参与父级排序,内部大数值不能越级。
- 常见触发:定位与 z-index、transform、opacity、isolation。
- 排查:遮挡、定位和裁剪分别检查。
- 弹层:统一根容器或合适的 top layer,仍需处理交互语义。
公司面试真题
这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。
浏览公司面试真题 →