z-index
我对 z-index 的理解至今仅停留在 定义一个元素在屏幕Z轴上的堆叠顺序,然而这是比较片面的一种理解
z-index并不是在任意地方都有效。它仅在 定义了position属性且值不为static的元素上生效判断元素在
Z轴上的堆叠顺序,不仅要比较z-index的大小,还会由元素的层叠上下文、层叠等级共同决定
所以要理解 z-index 需要理解下面几个概念
层叠上下文
层叠等级
层叠顺序
层叠上下文
在 CSS2.1 规范中,每个盒模型的位置是由三个维度决定的,分别是画布上的 X轴、Y轴 以及表示层叠的 Z轴
正常情况下我们只能观察到元素在 X轴Y轴 上的分布,却看不出它们在 Z轴 上的层叠关系;但如果元素发生了堆叠,此时就能发现某些元素之间会出现相互覆盖的情况
如果一个元素产生了层叠上下文,那么它就是 层叠上下文元素,没有的我们暂称为普通元素
HTML 的根元素 <html></html> 存在一个 根层叠上下文
普通元素其实就在根层叠上下文中,但大家的上下文都一样,可以理解成大家都没有上下文
符合以下条件的元素,会产生层叠上下文,其自身变为层叠上下文元素
HTML的根元素<html></html>本身就具有层叠上下文,为根层叠上下文普通元素设置
position为非static的值且设置z-index为具体数值使用了 CSS3 中部分新属性
层叠等级、层叠顺序
层叠等级由层叠顺序和 z-index 联合得出,层叠顺序是一种规定,如下图

CSS3 属性的影响
元素属性满足以上条件之一,就会产生层叠上下文:
父元素的
display属性值为flex|inline-flex,子元素z-index属性值不为auto的时候,子元素为层叠上下文元素,会产生层叠上下文元素的
opacity属性值不是1元素的
transform属性值不是none元素
mix-blend-mode属性值不是normal元素的
filter属性值不是none元素的
isolation属性值是isolatewill-change指定的属性值为上面任意一个元素的
-webkit-overflow-scrolling属性值设置为touch
决定层叠的次序
先找到元素最近的 层叠上下文(普通元素的层叠上下文相同,均为根层叠上下文)
如果
- 元素在同一个层叠上下文中,那么直接根据元素自身
z-index和层叠顺序得出层叠等级,从而决定顺序
否则
比较元素所在的
层叠上下文元素的z-index元素所在层叠上下文元素的
z-index较大者的元素层叠等级更高若
z-index相同,则在文档中顺序靠后的层叠等级更高
例一
1 | <style> |
其结果为

分析:
寻找
.a .b .c三元素的层叠上下文.box有position: relative;,但没有z-index,所以三个元素都是普通元素,都在根层叠上下文中三者都是
block且没有浮动直接比较
z-index得出顺序.a > .b > .c
例二
在例一基础上给两个 .box 加上 z-index
1 | <style> |
结果:

分析:
寻找
.a .b .c三元素的层叠上下文.a .b,.c分别在.b1,.b2的层叠上下文中根据
z-index判断.b2在.b1之上,.a在.b之上得出
.c > .a > .b
例三
1 | <style> |
此时结果为:

分析:
.parent,.child的层叠上下文都是根层叠上下文比较
z-index可以直接得出.parent > .child
我们给 .box 添加 display: flex;,此时结果发生了变化:

分析:
.parent因为父元素是flex,其自身形成了层叠上下文,成为层叠上下文元素此时因为
层叠顺序中的规则,层叠上下文元素的子元素必定在其background/border上方,所以.child > .parent





