堆疊上下文

**堆疊上下文**是 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;
}

結果

另請參閱