由z-index属性,引发对层叠上下文的全面认知

瘢壳枚举
• 阅读 1290

在日常开发中,经常使用z-index样式属性调整元素的层级大小。一般情况下,都能达到元素之间覆盖效果的要求。但在某些场景下,不论定位元素z-index属性值设置多大,都无法在页面的最顶层呈现。虽然可以可以把该元素提升为<body>的直接子元素,并且确实可以达到效果,但比较繁琐,开发效率比较低下。为此,开始对z-index样式属性开始研究,但研究到最后发现:页面的渲染是由若干个图层通过层叠上下文的顺序,依次渲染而成。下面就层叠上下文全面说说。

层叠上下文(stacking context)

层叠上下文是HTML中的一个三维概念,是元素在z轴上的相对位置的描述。对于曾经通过photoshop设计稿来获取页面元素尺寸的开发者而言,层叠上下文和图层的概念非常类似。

元素形成层叠上下文的条件

  1. 文档根元素(<html>);
  2. position 值为 absolute(绝对定位)或 relative(相对定位)且 z-index 值不为 auto 的元素;
  3. position 值为 fixed(固定定位)或 sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持);
  4. flex (flex) 容器的子元素,且 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、
    backdrop-filter、
    perspective、
    clip-path、
    mask / mask-image / mask-border
  9. isolation 属性值为 isolate 的元素;
  10. will-change 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素;
  11. contain 属性值为 layout、paint 或包含它们其中之一的合成值(比如 contain: strict、contain: content)的元素。

层叠上下文之间的关系

层叠上下文的子元素在满足条件后可以形成一个新的子层叠上下文,从而整体上形成层叠上下文的树形关系(父子嵌套、兄弟平行)。

不同层叠上下文的各个子元素,其影响范围仅限于父级层叠上下文,而不会影响到其他层叠上下文。例如:

由z-index属性,引发对层叠上下文的全面认知

上图中:

  • 左侧中的main1和main2设置了z-index为0,形成了新的层叠上下文,并且main2的层级比main1大;move1设置了z-index为999999,但由于无法突破父级层叠上下文的限制,无法覆盖在move2的上面。
  • 右侧中的main1和main2设置了z-index为auto,无法形成了新的层叠上下文;move1和move2有共同的父级层叠上下文,由于move1设置了z-index为999999,所以可以覆盖在move2的上面。

试试看

层叠顺序(stacking order)

一个层叠上下文的子元素可以是层叠上下文,也可以不是层叠上下文。子元素在z轴上的顺序规则,是通过层叠顺序来表达的。具体如下图所示:

由z-index属性,引发对层叠上下文的全面认知

整体示意图

由z-index属性,引发对层叠上下文的全面认知

总结

z-index引发了对层叠上下文的全面认知。现在利用层叠上下文的逻辑,解释开头的现象:因为设置z-index属性的定位元素,其父元素为层叠上下文(也为定位元素),并且父元素并非位于整个页面的最高层级;所以设置z-index属性的定位元素,无论其z-index属性值设置多大,都无法突破父元素的限制,达到整个页面的最高层级。

在日常开发中,有很多开发者在面对元素层叠场景时,都会为每个相关元素添加z-index属性。希望这篇文章能对这种行为有所帮助,全面认知层叠上下文,减少非必要z-index属性的书写。

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Selenium 详解CSS定位
xpath定位是“屠龙刀”,那CSS定位就是"倚天剑了",相对xpath来说,具有语法简单,定位速度快等优点一、属性定位1、可以通过元素的id,class,tag标签这三个属性直接定位  表示id属性,如:kw.  表示class属性,如:.s\_ipt直接用标签名称,如:inpu
Stella981 Stella981
3年前
Python+Selenium自动化篇
本篇文字主要学习selenium定位页面元素的集中方法,以百度首页为例子。0.元素定位方法主要有:id定位:find\_element\_by\_id('')name定位:find\_element\_by\_name('')class定位:find\_element\_by\_class\_name(''
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
JS和CSS加载(渲染)机制不同
一、结论CSS可以在页面加载完成后随时渲染。举个例子:通过js给某个元素加一个id或者css,只要这个id或者css有对应的样式,此元素的样式就会自动生效。JS不可以在页面加载完成后生效。最明显的例子就是使用EasyUI的时候,iframe中哪些样式无效(EasyUi是依靠JS进行样式处理的,所以无法运行JS,那么样式也就无法设置。简单点说
Stella981 Stella981
3年前
CSS 分类 (Classification)
★★CSS分类属性(Classification)★★⑴CSS分类属性允许你控制如何显示元素,设置图像显示于另一元素中的何处,相对于其正常位置来定位元素,使用绝对值来定位元素,以及元素的可见度。⑵下面是常用的属性以及描述:!(https://oscimg.oschina.net/oscnet/00cb565
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这