Skip to main content

层叠上下文与层叠等级

一、层叠上下文与层叠等级

1、什么是层叠上下文

层叠上下文 (stacking context) 是一个三维概念,当页面元素发生堆叠时,就可能出现某个元素覆盖另一个元素的情况。普通元素一旦有了层叠上下文,其层叠水平就比普通元素高,在层叠上下文内部,元素的层叠水平受制于外部的层叠上下文。

2、什么是层叠等级

层叠等级 (stacking level) 表示元素在 Z 轴的上下层叠顺序,层叠等级由所在的层叠上下文决定,且只在当前层叠上下文中比较才有意义。

二、层叠上下文的应用

1、如何产生层叠上下文

HTML 中的根元素 <html></html> 本身就具有层叠上下文,称为“根层叠上下文”。对普通元素来说,可通过以下方法创建层叠上下文:

  • 设置 position(不为 static)和 z-index(不为 auto
  • 设置 displayflex〡inline-flex〡gridz-index(不为 auto
  • 设置 opacity(不为 1
  • 设置 transform(不为 none
  • 设置 mix-blend-mode(不为 normal
  • 设置 filter(不为 none
  • 设置 isolationisolate
  • 设置 -webkit-overflow-scrollingtouch
  • ...
注意

只设置 z-index 而没有设置 position 等属性时,元素还是普通元素,没有产生层叠上下文,因此 z-index 无效。

举个例子:

下面 a、b、c 三个的父元素都没有设置 z-index,也就没有产生层叠上下文,所以 a、b、c 都处于由 <html></html> 产生的根层叠上下文中,此时谁的 z-index 值大,谁在上面。

a

b

c

<div class="box1">
<p class="a">a</p>
<p class="b">b</p>
</div>
<div class="box2">
<p class="c">c</p>
</div>

再举个例子:

下面 c 的 z-index 值为 99,大于 a 和 b,但由于 a、b 的父元素 box1 产生的层叠上下文 z-index 值为 2,c 的父元素 box2 产生的层叠上下文 z-index 为 1,所以 c 永远在 a 和 b 下面。

a

b

c

<div class="box1">
<p class="a">a</p>
<p class="b">b</p>
</div>
<div class="box2">
<p class="c">c</p>
</div>

2、层叠顺序规则

层叠顺序 (stacking order) 表示元素发生层叠时按照特定的顺序规则在 Z轴 上垂直显示。

background / border
z-index < 0
block 块级水平盒子
float 浮动盒子
inline / inline-block 水平盒子
z-index: auto / 0
z-index > 0

3、z-index: auto / 0

单纯考虑层叠顺序,z-index: autoz-index: 0 在同一层级,但这两个属性值是有区别的。

举个例子:

下面 box1、box2 虽然设置了 position: relative,但在 z-index: auto 的情况下,这两个 div 还是普通元素,并没有产生层叠上下文。

所以,a、b 属于 <html></html> 元素的根层叠上下文中,谁的 z-index 值大谁在上面。

a

b

<div class="box1">
<p class="a">a</p>
</div>
<div class="box2">
<p class="b">b</p>
</div>

再举个例子:

把上面 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

<div class="box1">
<p class="a">a</p>
</div>
<div class="box2">
<p class="b">b</p>
</div>

三、总结

普通元素一旦有了层叠上下文,其层叠水平就比普通元素高,在层叠上下文内部,元素的层叠水平受制于外部的层叠上下文。

  • 如果层叠上下文元素不依赖 z-index,则其层叠顺序 z-index: auto 可看成 z-index: 0 级别;
  • 如果层叠上下文元素依赖 z-index,则其层叠顺序由 z-index 值决定。