返回知识库

产品与设计 · 布局基础

层叠顺序Z-Index

z-index 决定同一堆叠上下文内重叠元素的先后;父级新建堆叠上下文后,子级再高的值也只在自己父级里比较。

让弹窗到最前:z-index 与堆叠上下文

任务:把红色弹窗送到最上层。调 z-index、定位和父级堆叠上下文,看弹窗为什么会被低值遮罩压住。

任务:把红色弹窗送到最前。 调它的 z-index、定位,再给父容器加 opacity 新建堆叠上下文,看弹窗为什么突然输给低值遮罩。

弹窗 position
弹窗父容器
弹窗z-index 200在最前 ✓
遮罩(弹窗的叔叔元素)z-index 50

结果:弹窗 z-index 200 在最前。 同一堆叠上下文里数字大的盖小的:弹窗 200 > 遮罩 50,底层内容 auto 不参与比较。

知识点:从面板里读出的四条规律

面板已经把四条规律演给你看了,这里只命名和收口。

  • 已定位才生效:z-index 只对 position≠static 的元素(或 flex/grid item)起作用;static 时数字被忽略(面板切到 static 看「z-index 未生效」)。
  • 同上下文比数字:在同一堆叠上下文里,z-index 数字大的盖小的(调滑块超过 50 看弹窗反超遮罩)。
  • 父级会建墙:opacity<1、transform、filter、will-change,或 position+z-index≠auto 都会新建堆叠上下文(面板开 opacity 0.99 看「堆叠上下文墙」出现)。
  • 子级被困:父级一旦建上下文,子级再高的 z-index 也只在父级内部排序;父上下文整体作为一个层参与外层比较,所以外层低值能压住子级 9999(面板里弹窗被困就是这个原因)。

什么时候用 z-index,什么时候先查上下文

从症状出发,别一上来就改数字。

  • 用 z-index:元素已定位,需要在同一父级里调谁盖谁——下拉盖内容、Toast 盖弹窗、遮罩盖页面。
  • 先查上下文:z-index 已经很大却仍被压住、或弹层被裁切、或父子都设了大值却不生效,多半是某个祖先新建了堆叠上下文。
  • 别用它做布局:z-index 不是排版工具,只为重叠的临时层(下拉、弹窗、Toast、遮罩)维护小而有序的层级表,禁止随手 9999。

怎么用:从遮挡到修复的最短路径

按顺序排查,多数遮挡在三步内定位。

  1. 确认已定位:被压的元素设了 position≠static(或它是 flex/grid item)吗?没有就先加 position:relative。
  2. 找最近的堆叠上下文:沿祖先链查 opacity、transform、filter、will-change、position+z-index,任何一个都会把子级困住。
  3. 在正确的上下文给值:要么在父上下文内给一个合理的小数字,要么把弹层移到与遮挡者相同的上下文,再比较 z-index。

正反例:只改父容器一处 opacity

同一个弹窗 z-index:9999,目标都是盖住 z-index:50 的遮罩,仅父容器透明度不同。

正例父容器 opacity:1

弹窗 position:relative + z-index:9999,与遮罩在同一堆叠上下文里比较,9999 > 50,弹窗稳稳盖住遮罩。

反例父容器 opacity:0.99

只想做"淡淡一层"给父容器加 opacity:0.99,意外新建堆叠上下文;弹窗 9999 被困父级内部,父级以 auto 参与外层,遮罩 50 反超压住弹窗。

快速自测

弹窗设了 z-index:9999 却被 z-index:50 的遮罩盖住,最可能的原因是什么?

继续查证

术语的技术定义和行为以这些一手或权威资料为准。

下一步学

和本知识点经常一起出现的概念。