为什么具有z-index值的元素不能覆盖其子元素?

问题描述 投票:4回答:4

今天,经过四个小时的调试,我很难学会这条规则:

如果父元素具有任何值的z-index,无论您如何更改子元素的CSS,父元素永远不能覆盖(堆叠在其子元素之上)

我如何通过逻辑理解这种行为?规范中包含哪些内容?

代码(也在CodePen中):

.container {
  width: 600px;
  height: 600px;
  background-color: salmon;
  position: relative;
  z-index: 99;
  margin-top: 20px;
  padding-top: 10px;
}

h1 {
  background-color: pink;
  position: relative;
  z-index: -1;
  font-family: monospace;
}
<div class="container">
  <h1>1. I can never be covered by parent if my z-index is positive.</h1>
  <h1>2. Even when my z-index is nagative, I still can never be covered if my parent has any z-index at all.</h1>
</div>

enter image description here

css css-position z-index
4个回答
8
投票

您需要知道两件重要的事情:绘画顺序和堆叠背景。如果你参考the specification,你可以找到元素的绘制方式和时间。

  1. 堆叠上下文由z-索引顺序中的负z-索引(不包括0)形成的后代(最多为负数)然后是树顺序。

  1. 所有定位,不透明度或变换后代,按树顺序分为以下类别: 所有定位的后代都带有'z-index:auto'或'z-index:0',按树顺序排列。

  1. 堆叠由z-index顺序(最小的第一个)的z-indices大于或等于1的定位后代形成的上下文,然后是树顺序。

由此可见,我们首先在步骤(3)中绘制具有负z-index的元素,然后在步骤(8)中使用z-index等于0的元素,最后在步骤(9)中具有正z-index的元素,这是合乎逻辑的。我们还可以阅读:

每个框属于一个堆叠上下文。给定堆叠上下文中的每个框具有整数堆栈级别,这是其在z轴上相对于同一堆叠上下文中的其他框的位置。具有更高堆栈级别的盒子总是在具有较低堆栈级别的盒子前面格式化。框可能具有负的堆栈级别。堆叠上下文中具有相同堆栈级别的框根据文档树顺序从下到上堆叠。

建立本地堆栈上下文的元素生成一个具有两个堆栈级别的框:一个用于它创建的堆栈上下文(总是0),另一个用于它所属的堆栈上下文(由z-index属性给出)。


要了解每个元素的绘制时间,您需要知道其堆叠上下文及其堆栈上下文中的堆栈级别(由z-index定义)。您还需要知道该元素是否建立堆叠上下文。这是棘手的部分,因为设置z-index将执行此操作:

对于定位框,z-index属性指定:

  1. 当前堆叠上下文中框的堆栈级别。
  2. 框是否建立堆叠上下文

此整数是当前堆叠上下文中生成的框的堆栈级别。该框还会建立新的堆叠上下文。


现在我们掌握了所有信息,以便更好地了解每个案例。如果父元素的z-index值不是auto,那么它将创建一个堆叠上下文,因此子元素将被绘制在z-index所在的内部(负面或正面)。子元素的z-index将简单地告诉我们父元素内部的绘画顺序(这涵盖了你的第二点)。

现在,如果只有子元素具有正z-index并且我们在父元素上没有设置任何内容,那么考虑绘制顺序,将在稍后(步骤(9))和步骤(8)中的父项绘制子项。绘制上面父级的唯一合理方法是增加z-index,但这样做会使我们陷入前一种情况,即父级将建立堆叠上下文并且子元素将属于它。

在为孩子设置正z-index时,无法将父元素置于子元素之上。如果我们将z-index设置为与auto不同的父元素(正面或负面),也无法将父元素置于子元素之上。

我们可以在其父元素下面生成子元素的唯一情况是在子元素上设置负z-index并将父元素保持在z-index: auto,因此这个不会创建堆叠上下文并且遵循绘制顺序将首先绘制子元素。


除了z-index,还有other properties that create a stacking context。如果您面临预期的堆叠订单,您还需要考虑这些属性,以便查看是否创建了堆叠上下文。


2
投票

The Mozilla documentation确实说

z-index CSS属性设置定位元素及其后代或弹性项的z顺序。

以下是another StackOverflow article关于儿童与后代的一些额外逻辑。


1
投票

考虑这个问题的好方法是每个父级都包含自己的堆叠上下文。同级元素共享父级的堆叠顺序,因此可能相互重叠。

子元素始终基于其父元素获取堆叠上下文。因此需要负z-索引值来将孩子推到其父(0)堆叠上下文“后面”。

从父项上下文中删除元素的唯一方法是使用position: fixed,因为这实际上强制它使用窗口作为上下文。


-1
投票

我如何通过逻辑理解这种行为?

对我来说,通过逻辑很难理解你的问题。父级包含其子级。一个碗可以被另一个碗盖住。但除非你把汤从碗里拿出来,否则你不能用碗盖汤。

z-Index设置重叠元素的顺序。父母不能与其子女重叠。

ImhO,这是完全合乎逻辑的。

© www.soinside.com 2019 - 2024. All rights reserved.