CSS 层叠上下文

背景

你有没有在项目中遇到过这种情况,自己写的组件需要有更高的展示层级,于是尝试改变z-index的值来调整层级顺序,但是无论怎样调整z-index的值都无法达到预期效果。也就是说,虽然我们把当前组件的z-index设为了9999999+也无济于事,那么此时我们就进入了一个误区。

举个🌰

假如我们有以下代码:

html 复制代码
<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,每个层叠上下文都遵循以下规则进行展示:

  1. 执行堆叠的根元素。
  2. 有设定positionz-index负数的元素和它们的子元素-1-2前面。
  3. 没有设定position的元素,一般元素。
  4. 有设定positionz-indexauto,设定opacity小于1和其他transforms等属性也在此列。
  5. 有设定positionz-index为正数。
  6. 都一样的时候就按文件中代码出现的先后顺序,后出现的出现在上面。

产生机制

每个层叠上下文中可以嵌套别的层叠上下文,每个层叠上下文中都按同一套层叠顺序规则进行展示。层叠上下文的创建有多种方式:

  1. 文档根元素,根<html></html>
  2. position 值为 absolute(绝对定位)或 relative(相对定位)且 z-index 值不为 auto 的元素
  3. position 值为 fixed(固定定位)或 sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持);
  4. flex (flexbox (en-US)) 容器的子元素,且 z-index 值不为 auto
  5. grid (grid) 容器的子元素,且 z-index 值不为 auto
  6. opacity 属性值小于 1 的元素(参见the specification for opacity
  7. mix-blend-mode 属性值不为 normal 的元素
  8. 以下任意属性值不为 none 的元素:
  • transform
  • filter
  • perspective
  • clip-path
  • mask/mask-image/mask-border
  1. isolation 属性值为 isolate 的元素
  2. -webkit-overflow-scrolling 属性值为 touch 的元素
  3. will-change 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素(参考这篇文章);
  4. contain 属性值为 layoutpaint 或包含它们其中之一的合成值(比如 contain: strictcontain: content)的元素。

应用

产生了层叠上下文之后,就会按照层叠顺序进行展示,这个过程会应用到浏览器的分层合成机制中

浏览器分层合成机制将网页内容分成多个图层,每个图层都可以独立地渲染。这样可以减少页面重新绘制的需要,提高了性能和响应速度

浏览器会根据布局树生成图层树,为了生成图层树,需要两个条件:

  1. 拥有层叠上下文属性的元素会被提升为单独的一层
  2. 需要剪裁(clip)的地方也会被创建为图层

示例中的图层树如下所示:

总结

  • 因此,当我们的某个元素已经创建了层叠上下文环境(stacking contetxt),那么它里面的元素再怎么设置z-index也不会影响它的父元素的层叠顺序,也就是说它只能和它所在的层叠上下文环境中的元素进行比较,而他的父元素的堆叠顺序决定了他在父元素所处环境中的位置。
  • 也就是说当我们把z-index设得很大却无济于事的时候,很可能该元素的上层元素已经具备stacking context了。
  • 所以,为了达到我们在demo中想要的效果其实也很简单,只要把stacking-context1z-index改为3即可。

参考

相关推荐
犹豫的果冻布丁2 分钟前
从零给 DeepSeek Harness 写一个壁纸皮肤插件(已开源)
前端·后端
漏刻有时21 分钟前
数据可视化Three.js 3D 地图实战:单文件原生实现省域区县拉伸建模
前端
会说话的番茄27 分钟前
AI 满嘴跑火车怎么办?给它配个"小抄"
前端·aigc
计算机魔术师29 分钟前
AI 权力集中辩论实录:从「token 工厂」到「唯一幸存者」
前端
eric-sjq34 分钟前
WanlyFrontend 中文声明式前端语言完全指南:让 0.6B 模型写出漂亮网页
前端
Full Stack Developme37 分钟前
跨站请求伪造 (CSRF) 是什么 设计及工作原理
前端·okhttp·csrf
MoSTChillax1 小时前
UI规范设计:从视觉到交互的全面指南
前端·ui·产品经理·设计规范·vibecoding
雪碧聊技术1 小时前
Vue + Element Plus 实现文本溢出显示省略号及悬浮提示
前端·javascript·css·vue.js·文本溢出省略
eric-sjq1 小时前
0.6B 前端生成模型本地部署实战:消费级显卡跑通 WanlyFrontend 全流程
前端·本地部署
小妖6662 小时前
设置了 box-sizing: border-box; 不管用,下边框还是被挤压没了
前端·css·html