前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >CSS 层叠上下文实战

CSS 层叠上下文实战

原创
作者头像
永恒的财宝
发布2024-11-22 14:22:51
发布2024-11-22 14:22:51
1481
举报

文章开始之前,推荐一些别人写的很好的文章!感兴趣的也可以去读一下哦!

今日推荐:苹果字体 PingFang SC 的一些踩坑记录

文章链接:https://cloud.tencent.com/developer/article/2391492

虽然最终解决方案个人不太认同,但确实是个挺有意思的场景。而我更推荐网站方自己引入字体文件,而不是依赖系统字体,至于字体文件优化可见 前端字体文件的引用与压缩


导言

官方文档可先见:https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_positioned_layout/Understanding_z-index/Stacking_context

你在使用 bootstrap 的模态框时,是否出现过背景遮罩始终盖住模态框的情况,

哪怕给模态框 z-index 改为极高也没用,只有把模态框添加到 body 之下才恢复正常。

预览:https://codepen.io/foreverZ133/pen/GbMKXd

这就 CSS 层叠上下文涉及到的问题,本文将梳理各种场景让你理解它。

什么是层叠上下文和层叠水平

所有的上下文都代表着存储着某些关联信息,比如执行上下文、块级格式化上下文等等。

当进行定位布局的渲染时,如何标记这堆元素的覆盖关系呢,在指定点击事件时是怎么知道会先碰到最上层的元素的呢?

层叠上下文可以把它理解为,屏幕为 xy 轴的二维平面,还有个眼睛垂直于屏幕的 z 轴,在屏幕前后三维空间的元素会覆盖屏幕或被屏幕挡住的表现

层叠水平,则是在相同 z 轴值时,多个元素在此平面上的遮挡表现。

形成层叠上下文

代码语言:txt
复制
body
  - red【普通元素】
  - green【普通元素】
遮挡关系的默认场景
遮挡关系的默认场景

预览:https://codepen.io/foreverZ133/pen/WNvOyym

通常情况下,兄弟节点总是后者覆盖前者的。

注意:仅讨论 display: bock 的情况,其他 display 会有另一套规则


但当某元素被创建层叠上下文后,它在 z 轴上会比普通元素高上一层而能覆盖普通元素。

注:z-index 属性有些特殊,比如:浏览器不区分 z-index: auto 或 z-index 负值只有定位时有效,等

添加以下属性即可创建层叠上下文 (随着 CSS3 属性还在增加,本表不全)

  • z-index 不为 auto 的 relative(此条有争议,比如 chrome79 没管 z-index)
  • absolute, fixed
  • z-index 不为 auto 的 flex 子项
  • opacity 不为 1
  • transform 不为 none
  • perspective 不为 none
  • filter 不为 none
  • mix-blend-mode 不为 normal
  • 带有 isolation: isolate
  • will-change 不为 none
  • 带有 -webkit-overflow-scrolling: touch
代码语言:txt
复制
body
  - red【含层叠上下文】
  - green【普通元素】
含层叠上下文的遮挡情况
含层叠上下文的遮挡情况

预览:https://codepen.io/foreverZ133/pen/dyoRKgV

同级层叠水平后者居上

当存在处于同个 z-index 的层叠上下文时,即同级层叠水平,

那么会表现为 后者居上(注意:父级祖父级不能含有层叠上下文)

代码语言:txt
复制
body
  - gray【普通元素】
    - red【含层叠上下文,z-index: auto】
  - pink【普通元素】
    - green【含层叠上下文,z-index: auto】
同级层叠水平的后者居上
同级层叠水平的后者居上

预览:https://codepen.io/foreverZ133/pen/XWbgYLj

不同级层叠水平大者居上

注:z-index 好像不同浏览器版本有差异,如需 z-index 生效最好加上 relative。

代码语言:txt
复制
body
  - gray【普通元素】
    - red【含层叠上下文,z-index: 1】
  - pink【普通元素】
    - green【含层叠上下文,z-index: auto】
不同级层叠水平的大着居上
不同级层叠水平的大着居上

预览:https://codepen.io/foreverZ133/pen/zYGdgOP

层叠水平的嵌套

当父级或祖父级元素含有层叠上下文时,内部的层叠上下文类似于水平的水平这样的嵌套关系。

这意味着,当父级层叠水平不够高时,子级的层叠水平再高也没用。

代码语言:txt
复制
body
  - gray【含层叠上下文,z-index: auto】
    - red【含层叠上下文,z-index: 999】
  - pink【含层叠上下文,z-index: auto】
    - green【含层叠上下文,z-index: 1】
层叠上下文嵌套时先判父级
层叠上下文嵌套时先判父级

预览:https://codepen.io/foreverZ133/pen/ZEGXdJY

负值的层叠上下文

先看通常场景,如果父级不含层叠上下文,负值的层叠水平会以屏幕为基准。

代码语言:txt
复制
body
  - gray【普通元素】
    - red【普通元素】
    - green【含层叠上下文,z-index: -1】
父级无层叠上下文时,负值的层叠水平会以屏幕为准
父级无层叠上下文时,负值的层叠水平会以屏幕为准

预览:https://codepen.io/foreverZ133/pen/dyoVBJV

而如果父级含层叠上下文,负值的层叠水平会以父级为基准。

代码语言:txt
复制
body
  - gray【含层叠上下文,z-index: auto】
    - red【普通元素】
    - green【含层叠上下文,z-index: -1】
父级有层叠上下文时,负值的层叠水平会以父级为准
父级有层叠上下文时,负值的层叠水平会以父级为准

预览:https://codepen.io/foreverZ133/pen/XWbeLZd

总结

以上便是创建层叠上下文后与众不同的视觉表现的规律。

可以在遇到奇怪的覆盖样式问题时有一定理论思路:https://codepen.io/foreverZ133/pen/GbMKXd

也可利用水平嵌套时 z-index: -1 的表现制作更多优秀效果:https://codepen.io/foreverZ133/pen/EBoWBd

还可以利用层叠上下文高于普通元素的表现区别于普通元素的覆盖问题:https://codepen.io/foreverZ133/pen/jjYOyo

更多案例:

https://codepen.io/foreverZ133/pen/orpZKR

https://codepen.io/hexagoncircle/pen/JZNVdE

思考题:层叠上下文的底层实现

假如你正在开发一款基于 canvas 的布局工具,假设元素的数据结构如下:

代码语言:js
复制
[
  selector: '',
  rect: { x: 0, y: 0, width: 100, height: 100, zIndex: 1 },
  children: [{
    selector: '',
    rect: { x: 0, y: 0, width: 100, height: 100 },
  }],
]

你也会遇到元素层叠的需求,通常是从上至下递归,那渲染覆盖关系就复杂了。

难道是递归两次,先找出层叠的部分,在实际渲染时再处理覆盖关系。

如果是上面这种,那第一次递归时应该存怎样的上下文数据。

类似如此,我还是挺好奇浏览器的实现的,但还未能找到相关官方文档。

思考题:非层叠上下文时的覆盖关系

在研究过程中,我发现了一些奇特的规律,

比如 inline-block 始终高于其他 display 的元素,

或者,文字与背景中间还能再覆盖其他元素等。

可点开右侧链接来体验:https://codepen.io/foreverZ133/pen/LKpqOj/


邀请人:一起重学前端

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导言
  • 什么是层叠上下文和层叠水平
  • 形成层叠上下文
  • 同级层叠水平后者居上
  • 不同级层叠水平大者居上
  • 层叠水平的嵌套
  • 负值的层叠上下文
  • 总结
    • 思考题:层叠上下文的底层实现
  • 思考题:非层叠上下文时的覆盖关系
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档