父元素z-index无法约束子元素层级,子元素显示于父元素兄弟上方的疑问
问题还原
你的代码结构中,.container是相对定位容器,内部包含#greeting(红色块)和.thing-container(绝对定位、z-index:-1),.thing-container的子元素.things(黑色块)却显示在#greeting上方,给.things设置z-index:-1后问题解决,但你疑惑为何父元素的z-index无法约束子元素层级。
核心原因:堆叠上下文的作用范围
问题出在堆叠上下文的创建条件上,父元素的z-index能约束子元素层级的前提是:父元素必须创建了独立的堆叠上下文。具体拆解你的代码:
.container设置了position: relative但未指定z-index(默认值为auto),因此它没有创建独立的堆叠上下文。这意味着.thing-container的z-index不是相对于.container,而是相对于整个文档的初始堆叠上下文(即<html>元素)。.thing-container是position: absolute且z-index: -1,它会创建自己的堆叠上下文。在这个上下文内部,子元素.things默认的堆叠层级是最高的(未设置z-index时,属于上下文内的优先渲染层级)。虽然.thing-container在初始上下文里是负层级,理论上应该在#greeting下方,但如果.container没有背景色,.thing-container的定位覆盖了#greeting的位置,视觉上会让你误以为.things在上方。当你给
.things设置z-index: -1后,它在.thing-container的堆叠上下文里变成了负层级,会被放到.thing-container的背景下方,自然就不会出现在#greeting上方了。
关键结论
- 只有当父元素满足创建堆叠上下文的条件时(比如
position不为static且z-index不为auto,或是flex/grid子元素等),子元素的z-index才会相对于父元素生效,父元素的层级才能约束子元素的范围。 - 如果父元素没有创建堆叠上下文,子元素的z-index是相对于更上层的堆叠上下文(通常是初始上下文),这时候父元素的z-index无法限制子元素的层级。
内容的提问来源于stack exchange,提问作者haiter

