css中的层叠上下文元素与层叠顺序

作者 likaiqiang 日期 2019-05-06
css中的层叠上下文元素与层叠顺序

什么是层叠上下文元素

css世界里是有z轴的,页面上的元素在z轴上发生层叠所遵循的规则(谁覆盖谁)称之为层叠规则。

层叠规则的被作用者又分为普通元素与层叠上下文元素。普通元素就不说了,那么哪些元素属于层叠上下文元素?

  1. html根元素
  2. z-index的值是数字的定位元素
  3. 其他css3元素

3.1 z-index值不为auto的flex项(父元素display:flex|inline-flex)

3.2 元素的opacity值不是1

3.3 元素的transform值不是none

3.4 元素mix-blend-mode值不是normal

3.5 元素的filter值不是none

3.6 元素的isolation值是isolate

3.7 will-change指定的属性值为上面任意一个

3.8 元素的-webkit-overflow-scrolling设为touch

每个层叠上下文元素都会创建一个层叠上下文,应用一套层叠规则,和javascript里面的变量作用域有一拼(其实不一样,大家意会一下)。。。

由于html根元素也会创建层叠上下文,所以页面上的所有元素都拥有自己的层叠上下文。层叠规则只影响该层叠上下文元素的后代元素,与兄弟元素无关。

层叠上下文元素的层叠顺序

千言万语汇成一张图。一个层叠上下文元素其后代元素的层叠顺序遵循这张图。

如何比较两个元素的层叠顺序

首先找个每个元素所处的层叠上下文,其次判断该元素在它所在层叠上下文中所扮演的角色。

如果两个元素属于同一个层叠上下文,直接套用上图规则。如果属于不同层叠上下文,就需要比较它们各自所处的层叠上下文所对应的层叠上下文元素的层叠顺序,以此类推。

如果两个元素的层叠水平相同,则dom中位置靠后的覆盖靠前的。

好绕口,举几个例子

例子1:z-index不为0的定位元素

<div style="position:relative;z-index:0">
<img style="position:absolute;z-index:999" src="https://cdn.pixabay.com/photo/2018/06/29/08/15/doodle-3505459__340.png" alt="">
</div>
<div>
<img style="position:absolute;z-index:1" src="https://cdn.pixabay.com/photo/2019/04/28/09/16/crested-bunting-4162483__340.jpg" alt=""> <!-- 鸟图 -->
</div>

结果第二张图片覆盖在第一张图片上。你可能会觉得第二张图在dom中的位置位于第一张图的后面,所以它会覆盖在第一张图的上面,其实这块是层叠上下文起了作用,交换两个div的位置,结果仍然不变。原因如下:

第一张图所处的层叠上下文对应的层叠上下文元素是z-index值为0的div,而第二张图所处的层叠上下文对应的层叠上下文元素是html。两张图处于不同的层叠上下文中,这时比对两张图的层叠顺序就变成了比对z-index值为0的div与第二张图的层叠顺序,因为他们俩处于同一层叠上下文元素(html)的层叠上下文中。

套用层叠规则图,正的z-index高于z-index值为0的元素。

例子2:z-index不为0的flex子元素

<div class="box">
<div class="child a"></div>
<div class="child b"></div>
<div class="child c"></div>
</div>
.box{
display:flex;
align-items:center;
border:1px solid;
.child{
width:30px;
height:30px;
}
.a{
background:yellowgreen;
margin-right:-10px;
}
.b{
background:pink;
}
.c{
background:yellow;
}
}

结果:

b元素覆盖了a元素,因为他们俩都是普通元素,层叠水平一样,则后面的覆盖前面的。

我们给a元素一个z-index:0,a元素就是一个层叠上下文元素,a与b都处于html的层叠上下文中,套用层叠图,z-index为0的元素覆盖block元素。

如果a与b都是层叠上下文元素,他们的层叠水平一样,则后面的覆盖前面的。

(未完,待续)