你可能没搞懂的css层叠上下文(stacking context)
层叠上下文是个啥?其实,开发中有很多因它造成的奇奇怪怪的效果,你可能并不清楚。
我们举个🌰:
.green {
position: fixed; /* 留意这行代码,待会要改动它 */
background: green;
}
.orange {
position: absolute;
z-index: -1;
background: orange;
}
<div class="green">
<div class="orange"></div>
</div>
猜猜两种颜色的在显示上的“先后位置”?
直接贴效果图:

结果不难预料,橙色显示在绿色前面。估计你也会感慨:这算啥,不是很简单嘛。
别急,现在让我们仅仅改动一行代码:把div.green
元素的定位position: fixed
改为position: absolute
。
现在再来猜猜,两种颜色现在的“先后位置”又是啥?
我们来看看现在的结果,橙色跑到了后面。

为什么会这样?
如果你也有这样的疑惑,想弄明白具体原因,就得好好了解一下层叠上下文了。
层叠上下文(stacking context),是一块由某个元素创建的区域,它规定了该区域中的内容在Z轴上排列的先后顺序。
这里说的先后顺序,就是刚才三种颜色在显示上的“先后位置”。
常见的创建层叠上下文的元素:
html
元素z-index
的值不为auto
的定位元素position
值为fixed
或sticky
的元素opacity
值小于1transform
/filter
/backdrop-filter
/perspective
/clip-path
/mask
/mask-image
/mask-border
里任意属性值不为none
的元素
同一个层叠上下文中元素在Z轴上的排列顺序
从后到前的排列顺序:
- 创建层叠上下文的元素的背景、边框
z-index
为负值的层叠上下文- 常规流非定位的块盒
- 非定位的浮动盒
- 常规流非定位的行盒、行块盒(ps:行盒、行块盒都只存在于常规流中)
- 任何
z-index
值是auto
或0
的定位元素、层叠上下文(ps: 多重同顺序的属性组合不影响顺序。例如同时设置了opacity: 0.9;position:relative;
的元素,跟只设置了opacity: 0.9;
的元素,在排列顺序上同级) z-index
为正值的层叠上下文- 多个同顺序的兄弟元素,后覆盖前
每个创建层叠上下文的元素及其子元素,它们在Z轴上排列的先后顺序视为一个整体。
现在我们来回答一开始的问题:
一开始的🌰里,div.green
、div.orange
两个元素处于由div.green
创建的同一个层叠上下文中。而创建上下文的元素div.green
的背景将处于排序的底层,所以橙色显示在前。
之后,div.green
改为了绝对定位后,它本身不再创建层叠上下文。此时div.green
、div.orange
同处于html
创建的上下文中,此时元素div.orange
命中排序2,div.green
命中排序6,所以橙色在绿色后面。
其实,CSS3的出现,让元素创建层叠上下文的方式变得很恶心。一个很有代表性的🌰就是,z-index
不再必须和定位元素一起使用才有作用,非定位元素也能和z-index
配合搞基,创建出层叠上下文,这颠覆了我们对z-index
的传统理解。
另外多提一嘴,body
元素极为特殊,千万不要用将其当成普通常规流非定位的块盒,应用在以上规则中,不然你会大跌眼镜。body
元素的奇怪现象远不止此🌰,这里不一一列举。
转载自:https://juejin.cn/post/7209617649885528122