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

标签 css css-position z-index

今天,经过数小时的调试,我很难学到了以下规则:

如果父级的z-index值为任何值,则无论您如何更改子级的CSS,父级元素都永远无法覆盖(堆叠在其子级元素之上)

如何通过逻辑理解这种行为?规范在哪里覆盖?



.container {
  width: 600px;
  height: 600px;
  background-color: salmon;
  position: relative;
  z-index: 99;
  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

最佳答案

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


  
  堆叠由具有负z索引(不包括0)的后代按z索引顺序(最负数先)然后按树顺序形成的上下文。
  





  
  按树顺序排列的所有已定位,不透明或转换后代均属于以下类别:
  
  
  所有以“ z-index:auto”或“ z-index:0”排列的后代,按树顺序排列。
  
  





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


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


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





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




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


  对于定位框,z-index属性指定:
  
  
  当前堆栈上下文中框的堆栈级别。
  盒子是否建立堆叠环境
  
  
  值具有以下含义:
  
  <integer>
  
  该整数是当前堆栈上下文中生成的框的堆栈级别。该框还建立了一个新的堆栈上下文。
  
  auto
  
  当前堆栈上下文中生成的框的堆栈级别为0。除非框是根元素,否则框不会建立新的堆栈上下文。




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

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

为子级设置肯定的z-index时,无法将父级置于子级元素上方。如果将z-index设置为不同于auto的父元素(正数或负数),也无法使父项高于子项。1

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



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



我们可以从以上总结得出一些重要事实:


  
  堆栈上下文可以包含在其他堆栈上下文中,并一起创建堆栈上下文的层次结构。
  每个堆栈上下文完全独立于其同级:处理堆栈时仅考虑后代元素。
  每个堆叠上下文都是自包含的:将元素的内容堆叠之后,将按照父堆叠上下文的堆叠顺序考虑整个元素。 ref
  




1:如果我们考虑使用3D变换,则有一些骇人听闻的方法。

元素位于其父元素下的示例,即使该元素指定了z-index



.box {
  position:relative;
  z-index:0;
  height:80px;
  background:blue;
  transform-style: preserve-3d; /* This is important */
}
.box > div {
  margin:0 50px;
  height:100px;
  background:red; 
  z-index:-1; /* this will do nothing */
  transform:translateZ(-1px); /* this will do the magic */
}

<div class="box">
  <div></div>
</div>





另一个示例,我们可以在另一个堆叠上下文中将一个元素放置在两个元素之间:



.box {
  position: relative;
  z-index: 0;
  height: 80px;
  background: blue;
}

.box>div {
  margin: 0 50px;
  height: 100px;
  background: red;
  z-index: 5;
  transform: translateZ(2px);
}

.outside {
  height: 50px;
  background: green;
  margin: -10px 40px;
  transform: translateZ(1px);
}

body {
  transform-style: preserve-3d;
}

<div class="box">
  <div></div>
</div>

<div class="outside"></div>





我们还可以有一些疯狂的堆叠顺序,如下所示:



.box {
  width: 100px;
  height: 100px;
  position: absolute;
}

body {
  transform-style: preserve-3d;
}

<div class="box" style="top:100px;left:50px;background:red;"></div>
<div class="box" style="top: 50px;left: 115px;background:blue;"></div>
<div class="box" style="top: 101px;left: 170px;background:green;"></div>
<div class="box" style="top: 175px;left: 115px;background:purple;transform: rotateY(-1deg);"></div>





CSS circular stacking context

关于css - 为什么具有z-index值的元素不能覆盖其子级?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58721793/

相关文章:

html - 相对位置按钮没有一直向右对齐

javascript - Jquery/Ajax/CSS 在使用 Ajax 提交表单后显示/隐藏 div

html - 如何让固定位置在相对的顶部?

css - 无法在 CSS 和 HTML 中将我的文本 Logo 居中

css - 带有 CSS 转换的 Safari 渲染错误 - 深度排序/z-index 问题? (适用于 Chrome)

CSS 使 li 元素出现在 ul 之外

HTML、CSS - 下拉列表打开后的表单拉伸(stretch)

jquery - 翻转时如何在 UL 中添加类并在 LI 中处于事件状态

css - 在 div 旁边 float div

html - z-index 对多个元素没有按预期工作