CSS层叠上下文
背景
你有没有在项目中遇到过这种情况,自己写的组件需要有更高的展示层级,于是尝试改变z-index
的值来调整层级顺序,但是无论怎样调整z-index
的值都无法达到预期效果。也就是说,虽然我们把当前组件的z-index
设为了9999999+
也无济于事,那么此时我们就进入了一个误区。
举个🌰
假如我们有以下代码:
<style type="text/css">
.stacking-context1 {
height: 200px;
width: 200px;
background-color: green;
position: absolute;
z-index: 1;
transform: translateZ(0);
}
.stacking-context2 {
height: 200px;
width: 200px;
background-color: blue;
position: absolute;
left: 30px;
top: 30px;
z-index: 999;
transform: translateZ(0);
}
.stacking-context3 {
height: 200px;
width: 200px;
background-color: pink;
position: absolute;
top: 70px;
left: 70px;
z-index: 2;
transform: translateZ(0);
}
</style>
<div class="stacking-context1">
<span>z-index: 1</span>
<div class="stacking-context2">z-index: 999</div>
</div>
<div class="stacking-context3">z-index: 2</div>
完整代码见:stacking context test
我们想调整stacking-context2
的z-index,使其可以覆盖到stacking-context3
上面,如下图所示:
原理
"层叠上下文"是一种用于管理网页元素堆叠顺序和渲染的重要概念。它决定了元素如何在页面上叠加和显示,通常与元素的CSS属性和属性值有关。
层叠顺序
如下图所示,在CSS2.1的年代,网页的层叠顺序遵循以下规则:
最里层的层叠上下文
即为执行堆叠的根元素,也就是产生层叠上下文的元素,如示列中的stacking-context1、2、3
,每个层叠上下文都遵循以下规则进行展示:
- 执行堆叠的根元素。
- 有设定
position
且z-index
为负数
的元素和它们的子元素-1
在-2
前面。 - 没有设定
position
的元素,一般元素。 - 有设定
position
且z-index
为auto
,设定opacity
小于1
和其他transforms
等属性也在此列。 - 有设定
position
且z-index
为正数。 - 都一样的时候就按文件中代码出现的先后顺序,后出现的出现在上面。
产生机制
每个层叠上下文中可以嵌套别的层叠上下文,每个层叠上下文中都按同一套层叠顺序
规则进行展示。层叠上下文的创建有多种方式:
- 文档根元素,根
<html></html>
position
值为absolute
(绝对定位)或relative
(相对定位)且z-index
值不为auto
的元素position
值为fixed
(固定定位)或sticky
(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持);flex (flexbox (en-US))
容器的子元素,且z-index
值不为auto
grid (grid)
容器的子元素,且z-index
值不为auto
opacity
属性值小于1
的元素(参见the specification for opacity)mix-blend-mode
属性值不为normal
的元素- 以下任意属性值不为
none
的元素:
transform
filter
perspective
clip-path
mask/mask-image/mask-border
isolation
属性值为isolate
的元素-webkit-overflow-scrolling
属性值为touch
的元素will-change
值设定了任一属性而该属性在non-initial
值时会创建层叠上下文的元素(参考这篇文章);contain
属性值为layout
、paint
或包含它们其中之一的合成值(比如contain: strict
、contain: content
)的元素。
应用
产生了层叠上下文
之后,就会按照层叠顺序
进行展示,这个过程会应用到浏览器的分层合成
机制中
浏览器分层合成机制将网页内容分成多个图层,每个图层都可以独立地渲染。这样可以减少页面重新绘制的需要,提高了性能和响应速度
浏览器会根据布局树生成图层树,为了生成图层树,需要两个条件:
- 拥有
层叠上下文属性
的元素会被提升为单独的一层 - 需要剪裁(
clip
)的地方也会被创建为图层
示例中的图层树如下所示:
总结
- 因此,当我们的某个元素已经创建了
层叠上下文环境(stacking contetxt)
,那么它里面的元素再怎么设置z-index
也不会影响它的父元素的层叠顺序
,也就是说它只能和它所在的层叠上下文环境
中的元素进行比较,而他的父元素的堆叠顺序决定了他在父元素所处环境中的位置。 - 也就是说当我们把
z-index
设得很大却无济于事的时候,很可能该元素的上层元素已经具备stacking context
了。 - 所以,为了达到我们在demo中想要的效果其实也很简单,只要把
stacking-context1
的z-index
改为3
即可。
参考
转载自:https://juejin.cn/post/7282605849709051939