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
属性值是isolate
will-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