likes
comments
collection
share

你可能没搞懂的css层叠上下文(stacking context)

作者站长头像
站长
· 阅读数 26

层叠上下文是个啥?其实,开发中有很多因它造成的奇奇怪怪的效果,你可能并不清楚。

我们举个🌰:

.green {
    position: fixed; /* 留意这行代码,待会要改动它 */
    background: green;
}
.orange {
    position: absolute;
    z-index: -1;
    background: orange;
}
<div class="green">
    <div class="orange"></div>
</div>

猜猜两种颜色的在显示上的“先后位置”?

直接贴效果图:

你可能没搞懂的css层叠上下文(stacking context)

结果不难预料,橙色显示在绿色前面。估计你也会感慨:这算啥,不是很简单嘛。

别急,现在让我们仅仅改动一行代码:把div.green元素的定位position: fixed改为position: absolute

现在再来猜猜,两种颜色现在的“先后位置”又是啥?

我们来看看现在的结果,橙色跑到了后面。

你可能没搞懂的css层叠上下文(stacking context)

为什么会这样?

如果你也有这样的疑惑,想弄明白具体原因,就得好好了解一下层叠上下文了。

层叠上下文(stacking context),是一块由某个元素创建的区域,它规定了该区域中的内容在Z轴上排列的先后顺序。

这里说的先后顺序,就是刚才三种颜色在显示上的“先后位置”。

常见的创建层叠上下文的元素:

  1. html 元素
  2. z-index 的值不为auto的定位元素
  3. position 值为 fixedsticky 的元素
  4. opacity 值小于1
  5. transform/filter/backdrop-filter/perspective/clip-path/mask/mask-image/mask-border 里任意属性值不为 none 的元素

同一个层叠上下文中元素在Z轴上的排列顺序

从后到前的排列顺序:

  1. 创建层叠上下文的元素的背景、边框
  2. z-index 为负值的层叠上下文
  3. 常规流非定位的块盒
  4. 非定位的浮动盒
  5. 常规流非定位的行盒、行块盒(ps:行盒、行块盒都只存在于常规流中)
  6. 任何z-index 值是 auto0 的定位元素、层叠上下文(ps: 多重同顺序的属性组合不影响顺序。例如同时设置了opacity: 0.9;position:relative; 的元素,跟只设置了opacity: 0.9; 的元素,在排列顺序上同级)
  7. z-index 为正值的层叠上下文
  8. 多个同顺序的兄弟元素,后覆盖前

每个创建层叠上下文的元素及其子元素,它们在Z轴上排列的先后顺序视为一个整体。

现在我们来回答一开始的问题:

一开始的🌰里,div.greendiv.orange两个元素处于由div.green创建的同一个层叠上下文中。而创建上下文的元素div.green的背景将处于排序的底层,所以橙色显示在前。

之后,div.green改为了绝对定位后,它本身不再创建层叠上下文。此时div.greendiv.orange同处于html创建的上下文中,此时元素div.orange命中排序2,div.green命中排序6,所以橙色在绿色后面。

其实,CSS3的出现,让元素创建层叠上下文的方式变得很恶心。一个很有代表性的🌰就是,z-index不再必须和定位元素一起使用才有作用,非定位元素也能和z-index配合搞基,创建出层叠上下文,这颠覆了我们对z-index的传统理解。

另外多提一嘴,body元素极为特殊,千万不要用将其当成普通常规流非定位的块盒,应用在以上规则中,不然你会大跌眼镜。body元素的奇怪现象远不止此🌰,这里不一一列举。