资讯专栏INFORMATION COLUMN

彻底理解z-index,看完还是只会无厘头的设置9999你打我~~~~

bladefury / 2186人阅读

摘要:如果同级父元素不是层叠上下文元素就不需要看父元素的眼色了文章到这里就结束了,希望看完这篇文章的同学可以彻底理解。

今天写代码用antd-mobile的checkbox时候,想在内容文本后面添加一个icon,并且需要对这个icon绑定事件,发现绑定之后怎么也点不中,调试发现原来被层层嵌套的dom元素盖住了,肯定是z-index在作祟。可是按照我之前对z-index的了解(自信满满)却怎么也不能把他由“被盖住”改成“盖住别人”,在一通“盲改”代码之后,终于“盖住”其他dom元素了。然而心里总是在想难道之前自己对z-index的认知有问题么,抱着这样的心态决定重新去学习,下面进入正文

90%的前端开发对z-index的认知

其实我想说大部分前端开发是不重视css的,也就导致了对css的很多属性认知都是表面的,这其中z-index就是最典型的一个,下面列举的错误认知还请大家对号入座:

z-index值越大越“靠近我们” -- 最初级的认知

要搭配position: absolute | relative | fixed 使用才有用呢 -- 稍微进阶一些的认知

比较两个兄弟节点谁更“靠近我们”,要看他们的同级父元素的比较呢。-- 可能是大部分前端的终极认知了

例如下面的例子:要比较div1-1-1 和 div2-1 是要看div1 和 div2 的比较结果呢

如果以上三个大家都中枪了,没关系,看完这篇文章你就永远告别了,在遇到z-index的问题再也不会“盲改,乱试”了

三个概念 -- 层叠上下文、层叠水平、层叠顺序

层叠上下文(stacking context)
看到上下文这个关键词,我想大家应该会有一点概念,没错就是context。和你们认识的那个BFC、IFC里面的上下文是一个意思,其实我想说css世界里面看到context或者XXX上下文其实都是同一个意思,完全可以理解为自成一派,在自己的小世界里面随便折腾,不受其他的context影响。当然,这个context是可以被其他context包含同时也可以包含其他context

层叠水平(stacking level)
层叠水平决定了在同一个层叠上下文中元素在Z轴上的显示顺序。
页面中的所有元素(普通元素和层叠上下文元素)都有层叠水平。然而对普通元素的层叠水平探讨只局限在层叠上下文元素中。
注:大家千万不要把层叠水平和z-index混为一谈,尽管某些情况下z-index确实可以影响层叠水平,但是也只局限于具有层叠上下文的元素,而层叠水平是所有元素都存在的

层叠顺序(stacking order)
层叠顺序表示发生层叠时有着特定的垂直显示顺序(规则)。
即:网上这张很流行的规则

关于这张图有一些补充:
位于最下面的background/border特指层叠上下文元素的边框和背景色。每一个层叠顺序规则仅适用当前层叠上下文元素的小世界
inline水平盒子指的是包括inline/inline-block/inline-table元素的层叠顺序,他们都是同级别的
单纯从层叠水平上看,实际上z-index:0和auto是可以看成一样的,但是在层叠上下文领域有着根本性的差异

深入了解层叠上下文

特性

层叠上下文的层叠水平要比普通元素高
层叠上下文可以阻断元素的混合模式
层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的层叠上下文
每个层叠上下文和兄弟元素独立,也就是说,当进行层叠变化或者渲染的时候,只需要考虑后代元素
每个层叠上下文是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠上下文的层叠顺序中

如何创建

根元素 (HTML)
z-index 值不为 "auto"的 绝对/相对定位(在firefox/ie浏览器下position: fixed也是可以的)
一个 z-index 值不为 "auto"的 flex 项目 (flex item),即:父元素 display: flex|inline-flex
opacity 属性值小于 1 的元素(参考 the specification for opacity)
transform 属性值不为 "none"的元素
mix-blend-mode 属性值不为 "normal"的元素
filter值不为“none”的元素
perspective值不为“none”的元素
isolation 属性被设置为 "isolate"的元素
position: fixed
在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值(参考这篇文章)
-webkit-overflow-scrolling 属性被设置 "touch"的元素

层叠上下文与层叠顺序

文章中多次提到普通元素具备层叠上下文后层叠水平就会变高,那么他究竟在层叠顺序那个规则图的哪个位置呢
把目光向上锁定,第二条列举了12个可以创建层叠上下文的方法,我们把他分为两类:第二三条和其他。
依赖z-index取值的:位置取决于z-index的值
不依赖z-index取值的:在图中第二高的位置,即:z-index = auto 或者 0

用一个例子来说明:

111
222
.container {
  width: 500px;
  height: 500px;
  background-color: #000;
  color: #fff;
  transform: scale(1); 
  /* 给container创建层叠上下文 */
}
.div1 {
  padding: 50px;
  background-color: aqua;
  z-index: 0;
  position: relative;
  /* 给div1创建层叠上下文,层叠水平依赖z-index的取值 */
}
.div2 {
  padding: 50px;
  background-color: red;
  opacity: 0.8;
  /* 给div2创建层叠上下文,层叠水平依赖z-index的取值 */
  /* margin-top: -40px; */
}

这个例子中一目了然,div1和div2的层叠水平一样,都是在规则那张图的第二高的位置,不过div2在div1的dom节点后面,所以div2要比div1的层叠水平高,我们把margin-top的注释去掉看下:


要想使得div1在上面只需要把div1的z-index改成大于0的值就好了。

还是上面的htl结构,接下来我们再来看一个有意思的例子:

.container {
  width: 500px;
  height: 500px;
  background-color: #000;
  color: #fff;
  transform: scale(1);
  /* 给container创建层叠上下文 */
}
.div1 {
  padding: 50px;
  background-color: aqua;
  opacity: 0.8;
  /* 给div1创建层叠上下文,层叠水平在z-index:0 */
}
.div2 {
  padding: 50px;
  background-color: red;
  position: relative;
  margin-top: -40px;
}

大家肯定会说,div1明显盖过div2啊,可是我们来看下实际情况:

实际情况下面的div2盖过了div1,原因是当html元素设置定位属性的时候(absolute/relative),其z-index属性自动生效变成
z-index: auto,所以这时候div1和div2的层叠水平是一致的,而div2在div1的dom节点后面,所以盖过了div1(注意这里div2并没有变成层叠上下文元素,这是有本质区别的

常见错误认知解析

现在我们在一起看下文章开头提到的几个常见的错误认知:

z-index值越大越“靠近我们” -- 并不一定,首先要成为层叠上下文。或者如果比较的元素的父元素也是层叠上下文,那就完全取决于父元素了

要搭配position: absolute | relative | fixed 使用才有用呢 -- 对了一部分,还有其他的条件也可以使元素称为层叠上下文元素

比较两个兄弟节点谁更“靠近我们”,要看他们的同级父元素的比较呢。-- 如果同级父元素不是层叠上下文元素就不需要看“父元素的眼色”了

文章到这里就结束了,希望看完这篇文章的同学可以彻底理解z-index。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/55007.html

相关文章

  • 彻底理解z-index看完还是只会厘头设置9999打我~~~~

    摘要:如果同级父元素不是层叠上下文元素就不需要看父元素的眼色了文章到这里就结束了,希望看完这篇文章的同学可以彻底理解。 今天写代码用antd-mobile的checkbox时候,想在内容文本后面添加一个icon,并且需要对这个icon绑定事件,发现绑定之后怎么也点不中,调试发现原来被层层嵌套的dom元素盖住了,肯定是z-index在作祟。可是按照我之前对z-index的了解(自信满满)却怎么...

    RobinTang 评论0 收藏0
  • 彻底搞懂CSS层叠上下文、层叠等级、层叠顺序、z-index

    摘要:栗子有两个,被包裹在一个里,被包裹在另一个盒子里,同时为两个和设置和属性效果我们发下,虽然元素的值为,远大于和的值,但是由于的父元素产生的层叠上下文的的值为,的父元素所产生的层叠上下文的值为,所以永远在和下面。 前言 最近,在项目中遇到一个关于CSS中元素z-index属性的问题,具体问题不太好描述,总结起来就是当给元素和父元素色设置position属性和z-index相关属性后,页面...

    Steve_Wang_ 评论0 收藏0
  • 彻底搞懂CSS层叠上下文、层叠等级、层叠顺序、z-index

    摘要:栗子有两个,被包裹在一个里,被包裹在另一个盒子里,同时为两个和设置和属性效果我们发下,虽然元素的值为,远大于和的值,但是由于的父元素产生的层叠上下文的的值为,的父元素所产生的层叠上下文的值为,所以永远在和下面。 前言 最近,在项目中遇到一个关于CSS中元素z-index属性的问题,具体问题不太好描述,总结起来就是当给元素和父元素色设置position属性和z-index相关属性后,页面...

    Donne 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<