堆叠上下文
**堆叠上下文**是 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
- 顶层