z-index与堆叠上下文
z-index
说明:以下说到“定位元素”时,均指
position属性不为static的元素。
z-index 属性用于设置一个定位元素及其后代元素在Z轴(垂直屏幕的轴,指向屏幕外的方向为正)上的顺序(或层级)。
当元素与元素之间的位置有重叠时,z-index 较大的元素会覆盖较小的元素。
注意:
z-index的比较只在同一个堆叠上下文中有意义,在不同的堆叠上下文内比较z-index的大小来判断层级顺序的排布是毫无意义的。
值得一提的是在MDN文档中有提到
z-index属性还可以设定 flex 项目的 z-order。
但是我尚不理解是什么意思。
使用两个同级的定位元素和flex元素来测试,可是并没有出现更高z-index属性的flex元素覆盖更低z-index定位元素的情况。
除了几个全局的值 inherit、initial、unset 之外,z-index 属性可以设置的值有关键字 auto 和整数。
auto 与 0
在单纯的两个分别设置了 z-index: auto 和 z-index: 0 的定位元素进行比较层级时,二者的表现是一样的。
可以简单的认为 z-index: auto 的层级表现就是 0。
但是既然在这里单独拿出来比较二者有什么不同了,那肯定还是有区别的。
它们的不同之处就在于:
z-index: auto不会创建新的堆叠上下文,而z-index: 0会创建一个新的堆叠上下文。
堆叠上下文
什么是堆叠上下文?
首先我们需要简单了解一下页面中每个元素的绘制情况。
把页面想象成一个桌面(或者别的什么平台的一个平面),每个元素想象成一张薄纸,元素的绘制,就像是把一张张纸按顺序从顶部到底部平铺在桌面上。
这个桌面就是第一个堆叠上下文。
上面按顺序排列纸张就是HTML的一个正常的流式布局,那么定位呢?
定位就是把这张纸从正常的排序中拿出来,直接放在桌面上对应定位位置的地方,此时,这张纸跟其他的纸就可能会发生重叠的情况。
根据 z-index 的大小,来决定这张定位的纸是摆在正常纸张的上面还是下面(z-index 为负整数)。
如果给这张定位的纸设置的 z-index 不是 auto 的话,就会产生一个新的堆叠上下文,你可以想象,这张纸成了一个新的平台,而平台对比它所在平台(这里就是桌面)的高度就是它的 z-index 属性的值。
后续在这张定位的纸上继续添加纸张的话,新的纸都会基于新的平台来摆放,而不再是基于原本的桌面。
这就是堆叠上下文。
了解了堆叠上下文之后,大概就可以想到为什么上面提到了 z-index 只在同一个堆叠上下文中才有比较的意义了吧。
比如现在在一个堆叠上下文中有两个定位元素,第一个定位元素是 z-index: 1,第二个定位元素是 z-index: 100。
然后这两个定位元素中也分别有一个定位元素,第一个元素中的子定位元素是 z-index: 200,而第二个元素的子定位元素是 z-index: 1。
乍一看,z-index: 200 应该是最高的,但是它的上下文是 z-index: 1,不论这个子元素的层级有多高,也无法摆脱它所在的平台实在太低的事实。
同样的,第二个元素的子元素层级只有 1,可是它的平台高啊,所以你会看到实际情况是 第二个元素的子元素是高过第一个元素的子元素的。
然后当把第一个元素的 z-index: 1 改为 z-index: auto 之后,你会发现,它的子元素反过来盖住了第二个元素及其子元素,原因就是 z-index: auto 不会创建堆叠上下文,使得其子元素与第二个元素处于同一个堆叠上下文,而显然 200 > 100。
参考链接
- MDN z-index