堆疊上下文
**堆疊上下文**是 HTML 元素沿使用者假想 z 軸的三維概念化,使用者被假定為面對視口或網頁。HTML 元素根據元素屬性按優先順序順序佔據此空間。
描述
在本指南的上一篇文章 使用 z-index 中,我們展示了某些元素的渲染順序受其 z-index 值的影響。發生這種情況是因為這些元素具有特殊屬性,導致它們形成一個堆疊上下文。
在文件中的任何位置,以下情況下,任何元素都會形成堆疊上下文
- 文件的根元素 (
<html>)。 - 具有
position值absolute或relative以及z-index值非auto的元素。 - 具有
position值fixed或sticky的元素(對於所有移動瀏覽器,sticky均適用,但不適用於舊版桌面瀏覽器)。 - 具有
container-type值size或inline-size的元素,旨在用於 容器查詢。 - 彈性容器的子元素,其
z-index值非auto。 - 網格容器的子元素,其
z-index值非auto。 - 具有小於
1的opacity值的元素。 - 具有非
normal的mix-blend-mode值的元素。 - 具有以下任何屬性且值非
none的元素 - 具有
isolation值isolate的元素。 - 具有
will-change值的元素,該值指定任何將在非初始值上建立堆疊上下文的屬性。 - 具有
layout或paint的contain值,或包含其中任何一個的複合值(即contain: strict、contain: content)的元素。 - 放置到 頂層 及其相應的
::backdrop的元素。示例包括 全屏 和 彈出視窗 元素。 - 使用
@keyframes對其建立堆疊上下文屬性(如opacity)進行動畫處理的元素,且animation-fill-mode設定為forwards。
在堆疊上下文中,子元素根據上面解釋的相同規則進行堆疊。重要的是,其子堆疊上下文的 z-index 值僅在其父級中具有意義。堆疊上下文在父堆疊上下文中被視為單個原子單元。
總結
- 堆疊上下文可以包含在其他堆疊上下文中,並一起建立堆疊上下文的層次結構。
- 每個堆疊上下文與其同級完全獨立:在處理堆疊時,僅考慮後代元素。
- 每個堆疊上下文都是自包含的:在元素內容堆疊後,整個元素將在父堆疊上下文的堆疊順序中考慮。
注意: 堆疊上下文層次結構是 HTML 元素層次結構的子集,因為只有某些元素才會建立堆疊上下文。我們可以說,不建立自身堆疊上下文的元素會被父堆疊上下文吸收。
示例
在這個示例中,由於每個定位元素的位置和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 #5:(
- DIV #1:(
z-index:5)
- DIV #2:(
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
* {
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;
}
結果
另請參閱
- 不使用 z-index 屬性時的堆疊:不使用
z-index時適用的堆疊規則。 - 堆疊浮動元素:如何處理浮動元素的堆疊。
- 使用 z-index:如何使用
z-index更改預設堆疊。 - 堆疊上下文示例 1:2 級 HTML 層次結構,最後一級使用
z-index - 堆疊上下文示例 2:2 級 HTML 層次結構,所有級別都使用
z-index - 堆疊上下文示例 3:3 級 HTML 層次結構,第二級使用
z-index - 頂層