Sunday面试指南

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,而不是继续堆数值。

弹窗的高 z-index 只在父上下文内部生效,父级整体仍可能在导航栏之下

知识点详解:先找到排序的层,再比较数字

把 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,仍需处理交互语义。

公司面试真题

这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。

浏览公司面试真题 →
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历