层叠上下文与层叠等级
一、层叠上下文与层叠等级
1、什么是层叠上下文
层叠上下文 (stacking context) 是一个三维概念,当页面元素发生堆叠时,就可能出现某个元素覆盖另一个元素的情况。普通元素一旦有了层叠上下文,其层叠水平就比普通元素高,在层叠上下文内部,元素的层叠水平受制于外部的层叠上下文。
2、什么是层叠等级
层叠等级 (stacking level) 表示元素在 Z 轴的上下层叠顺序,层叠等级由所在的层叠上下文决定,且只在当前层叠上下文中比较才有意义。
二、层叠上下文的应用
1、如何产生层叠上下文
HTML
中的根元素 <html></html>
本身就具有层叠上下文,称为“根层叠上下文”。对普通元素来说,可通过以下方法创建层叠上下文:
- 设置
position
(不为 static)和z-index
(不为 auto) - 设置
display
为flex〡inline-flex〡grid
和z-index
(不为 auto) - 设置
opacity
(不为 1) - 设置
transform
(不为 none) - 设置
mix-blend-mode
(不为 normal) - 设置
filter
(不为 none) - 设置
isolation
为isolate
; - 设置
-webkit-overflow-scrolling
为touch
; - ...
只设置 z-index
而没有设置 position
等属性时,元素还是普通元素,没有产生层叠上下文,因此 z-index
无效。
举个例子:
下面 a、b、c 三个的父元素都没有设置 z-index
,也就没有产生层叠上下文,所以 a、b、c 都处于由 <html></html>
产生的根层叠上下文中,此时谁的 z-index
值大,谁在上面。
a
b
c
- HTML
- CSS
<div class="box1">
<p class="a">a</p>
<p class="b">b</p>
</div>
<div class="box2">
<p class="c">c</p>
</div>
.box1, .box2 {
position: relative;
}
.a, .b, .c {
position: absolute;
width: 100px;
height: 100px;
}
.a {
top: 0px;
left: 0px;
background-color: #8ADFDE;
z-index: 10;
}
.b {
top: 20px;
left: 20px;
background-color: #7FB4E4;
z-index: 20;
}
.c {
top: 40px;
left: 0px;
background-color: #918AEA;
z-index: 99;
}
再举个例子:
下面 c 的 z-index
值为 99,大于 a 和 b,但由于 a、b 的父元素 box1 产生的层叠上下文 z-index
值为 2,c 的父元素 box2 产生的层叠上下文 z-index
为 1,所以 c 永远在 a 和 b 下面。
a
b
c
- HTML
- CSS
<div class="box1">
<p class="a">a</p>
<p class="b">b</p>
</div>
<div class="box2">
<p class="c">c</p>
</div>
div {
position: relative;
}
.box1 {
z-index: 2;
}
.box2 {
z-index: 1;
}
.a, .b, .c {
position: absolute;
width: 100px;
height: 100px;
}
.a {
top: 0px;
left: 0px;
background-color: #8ADFDE;
z-index: 10;
}
.b {
top: 20px;
left: 20px;
background-color: #7FB4E4;
z-index: 20;
}
.c {
top: 40px;
left: 0px;
background-color: #918AEA;
z-index: 99;
}
2、层叠顺序规则
层叠顺序 (stacking order) 表示元素发生层叠时按照特定的顺序规则在 Z轴
上垂直显示。
3、z-index: auto / 0
单纯考虑层叠顺序,z-index: auto
和 z-index: 0
在同一层级,但这两个属性值是有区别的。
举个例子:
下面 box1、box2 虽然设置了 position: relative
,但在 z-index: auto
的情况下,这两个 div
还是普通元素,并没有产生层叠上下文。
所以,a、b 属于 <html></html>
元素的根层叠上下文中,谁的 z-index
值大谁在上面。
a
b
- HTML
- CSS
<div class="box1">
<p class="a">a</p>
</div>
<div class="box2">
<p class="b">b</p>
</div>
.box1, .box2 {
position: relative;
z-index: auto;
}
.a, .b {
position: absolute;
width: 100px;
height: 100px;
}
.a {
top: 0px;
left: 0px;
background-color: #8ADFDE;
z-index: 2;
}
.b {
top: 20px;
left: 20px;
background-color: #7FB4E4;
z-index: 1;
}
再举个例子:
把上面 box1、box2 的 z-index
改为 0
,其余不变,此时 b 会覆盖在 a 上面。
这是因为设置 z-index: 0
后,box1、box2 产生了各自的层叠上下文,这时 a、b 的层叠关系由父元素 box1、box2 的层叠关系决定。
而 box1、box2 的 z-index
都为 0
,且都是块级元素,这时在 DOM 结构中后面的覆盖前面的,所以 b
就在上面。
a
b
- HTML
- CSS
<div class="box1">
<p class="a">a</p>
</div>
<div class="box2">
<p class="b">b</p>
</div>
.box1, .box2 {
position: relative;
z-index: 0;
}
.a, .b {
position: absolute;
width: 100px;
height: 100px;
}
.a {
top: 0px;
left: 0px;
background-color: #8ADFDE;
z-index: 2;
}
.b {
top: 20px;
left: 20px;
background-color: #7FB4E4;
z-index: 1;
}
三、总结
普通元素一旦有了层叠上下文,其层叠水平就比普通元素高,在层叠上下文内部,元素的层叠水平受制于外部的层叠上下文。
- 如果层叠上下文元素不依赖
z-index
,则其层叠顺序z-index: auto
可看成z-index: 0
级别; - 如果层叠上下文元素依赖
z-index
,则其层叠顺序由z-index
值决定。