堆叠上下文

**堆叠上下文**是 HTML 元素沿用户假想 z 轴的三维概念化,用户被假定为面对视口或网页。HTML 元素根据元素属性按优先级顺序占据此空间。

描述

在本指南的上一篇文章 使用 z-index 中,我们展示了某些元素的渲染顺序受其 z-index 值的影响。发生这种情况是因为这些元素具有特殊属性,导致它们形成一个堆叠上下文

在文档中的任何位置,以下情况下,任何元素都会形成堆叠上下文

在堆叠上下文中,子元素根据上面解释的相同规则进行堆叠。重要的是,其子堆叠上下文的 z-index 值仅在其父级中具有意义。堆叠上下文在父堆叠上下文中被视为单个原子单元。

总结

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

注意: 堆叠上下文层次结构是 HTML 元素层次结构的子集,因为只有某些元素才会创建堆叠上下文。我们可以说,不创建自身堆叠上下文的元素会被父堆叠上下文吸收

示例

Example of stacking rules modified using z-index

在这个示例中,由于每个定位元素的位置和z-index值,它们都创建了自己的堆叠上下文。堆叠上下文的层次结构组织如下:

    • DIV #1
    • DIV #2
    • DIV #3
      • DIV #4
      • DIV #5
      • DIV #6

需要注意的是,DIV #4、DIV #5 和 DIV #6 是 DIV #3 的子元素,因此这些元素的堆叠完全在 DIV #3 内解决。一旦 DIV #3 内部的堆叠和渲染完成,整个 DIV #3 元素就会相对于其同级 DIV 在根元素中进行堆叠。

DIV #4 渲染在 DIV #1 下方,因为 DIV #1 的 z-index(5)在根元素的堆叠上下文中有效,而 DIV #4 的 z-index(6)在 DIV #3 的堆叠上下文中有效。所以,DIV #4 在 DIV #1 下方,因为 DIV #4 属于 DIV #3,而 DIV #3 的 z-index 值较低。

出于同样的原因,DIV #2(z-index:2)渲染在 DIV #5(z-index:1)下方,因为 DIV #5 属于 DIV #3,而 DIV #3 的 z-index 值较高。

DIV #3 的 z-index 为 4,但此值独立于 DIV #4、DIV #5 和 DIV #6 的 z-index,因为它属于不同的堆叠上下文。

一种简单的方法来确定沿 z 轴堆叠元素的渲染顺序,就是将其视为某种“版本号”,其中子元素是其父元素主要版本号下的次要版本号。这样,我们可以很容易地看到 z-index 为 1 的元素(DIV #5)如何堆叠在 z-index 为 2 的元素(DIV #2)之上,以及 z-index 为 6 的元素(DIV #4)如何堆叠在 z-index 为 5 的元素(DIV #1)之下。

在我们的示例中(根据最终渲染顺序排序):

    • DIV #2:(z-index:2)
    • DIV #3:(z-index:4)
      • DIV #5:(z-index:1),堆叠在一个(z-index:4)的元素下方,导致渲染顺序为 4.1
      • DIV #6:(z-index:3),堆叠在一个(z-index:4)的元素下方,导致渲染顺序为 4.3
      • DIV #4:(z-index:6),堆叠在一个(z-index:4)的元素下方,导致渲染顺序为 4.6
    • DIV #1:(z-index:5)

HTML

html
<div id="div1">
  <h1>Division Element #1</h1>
  <code>
    position: relative;<br />
    z-index: 5;
  </code>
</div>

<div id="div2">
  <h1>Division Element #2</h1>
  <code>
    position: relative;<br />
    z-index: 2;
  </code>
</div>

<div id="div3">
  <div id="div4">
    <h1>Division Element #4</h1>
    <code>
      position: relative;<br />
      z-index: 6;
    </code>
  </div>

  <h1>Division Element #3</h1>
  <code>
    position: absolute;<br />
    z-index: 4;
  </code>

  <div id="div5">
    <h1>Division Element #5</h1>
    <code>
      position: relative;<br />
      z-index: 1;
    </code>
  </div>

  <div id="div6">
    <h1>Division Element #6</h1>
    <code>
      position: absolute;<br />
      z-index: 3;
    </code>
  </div>
</div>

CSS

css
* {
  margin: 0;
}
html {
  padding: 20px;
  font:
    12px/20px Arial,
    sans-serif;
}
div {
  opacity: 0.7;
  position: relative;
}
h1 {
  font: inherit;
  font-weight: bold;
}
#div1,
#div2 {
  border: 1px dashed #696;
  padding: 10px;
  background-color: #cfc;
}
#div1 {
  z-index: 5;
  margin-bottom: 190px;
}
#div2 {
  z-index: 2;
}
#div3 {
  z-index: 4;
  opacity: 1;
  position: absolute;
  top: 40px;
  left: 180px;
  width: 330px;
  border: 1px dashed #900;
  background-color: #fdd;
  padding: 40px 20px 20px;
}
#div4,
#div5 {
  border: 1px dashed #996;
  background-color: #ffc;
}
#div4 {
  z-index: 6;
  margin-bottom: 15px;
  padding: 25px 10px 5px;
}
#div5 {
  z-index: 1;
  margin-top: 15px;
  padding: 5px 10px;
}
#div6 {
  z-index: 3;
  position: absolute;
  top: 20px;
  left: 180px;
  width: 150px;
  height: 125px;
  border: 1px dashed #009;
  padding-top: 125px;
  background-color: #ddf;
  text-align: center;
}

结果

另请参阅