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

时间:2019-02-27 04:09:34

标签: css css-position z-index

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

如果父级的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

4 个答案:

答案 0 :(得分:6)

您需要了解两件重要的事情:绘画顺序和堆叠上下文。如果您参考the specification,则可以找到绘制元素的方式和时间。

  
      
  1. 堆叠上下文是由定位的后代带有负z索引(不包括0)的z索引顺序(最负的是第一个)然后是树顺序形成的。
  2.   

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

  
      由具有 z索引大于或等于1 的定位后代形成的
  1. 堆叠上下文,按z索引顺序(最小的顺序为小),然后是树顺序。
  2.   

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

  

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

  

一个建立本地堆栈上下文的元素会生成一个具有两个堆栈级别的框:一个用于它创建的堆栈上下文(始终为0),另一个用于它所属的堆栈上下文(由z-index属性赋予)


要了解何时绘制每个元素,您需要了解此堆叠上下文(由z-index定义)中的其堆叠上下文其堆叠级别。您还需要知道该元素是否建立了堆栈上下文。这是棘手的部分,因为设置z-index可以做到这一点:

  

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

     
      
  1. 当前堆栈上下文中框的堆栈级别。
  2.   
  3. 盒子是否建立了堆叠环境
  4.   

  

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


现在,我们拥有所有信息,可以更好地理解每种情况。如果父元素的z-index值为z-index以外的其他值,则它将创建一个堆栈上下文,因此子元素将被绘制在其auto的内部(负数或正数) )。子元素的z-index会简单地告诉我们父元素(这是第二点)内的绘画顺序。

现在,如果仅子元素具有正数z-index,而我们在父元素上未设置任何内容,则考虑绘制顺序,子元素将在稍后绘制(在步骤(9)中),父元素在步骤(8)。在上面绘制父级的唯一合乎逻辑的方法是增加z-index,但是这样做会使我们陷入先前的情况,父级将建立一个堆栈上下文,而子元素将属于该上下文。

在为孩子设置肯定 z-index时,没有办法使父对象位于子元素上方。如果我们将z-index设置为不同于z-index的父元素(正数或负数),也没有没有办法使父项高于子项。

我们唯一可以在其父项之下有一个子项的情况是在子元素上设置一个负数auto并将父项保持在z-index,因此该子项不会创建堆栈上下文,并且按照绘画顺序,孩子将首先被绘画。


z-index: auto外,还有other properties that create a stacking context。如果遇到预期的堆叠顺序,则还需要考虑这些属性,以查看是否创建了堆叠上下文。

答案 1 :(得分:2)

The Mozilla documentation确实说

  

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

another StackOverflow article中还有一些关于孩子与后代的逻辑。

答案 2 :(得分:1)

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

子元素总是基于其父元素获得堆栈上下文。因此,需要有一个负的z-index值才能将子级推到其父级(0)堆栈上下文之后。

从元素的父上下文中删除元素的唯一方法是使用position: fixed,因为这实际上迫使该元素将窗口用于上下文。

答案 3 :(得分:0)

  

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

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

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

ImhO非常合乎逻辑。

相关问题