CSS进阶(16)—— CSS世界的层叠规则(下)

694 阅读7分钟

上一章我们主要了解了层叠上下文,层叠水平,CSS层叠领域的两大黄金法则等概念,本章我们讲继续深入探索CSS世界的层叠规则。

1.深入理解层叠上下文

“层叠上下文”的元素有如下的一些特性:

(1)默认层叠水平(z-index:auto)比普通元素要高

(2)可以阻断元素的混合模式

(3)可以嵌套,内部所有(层叠上下文及其所有普通子)元素均受制于外部的“层叠上下文”

(4)每个“层叠上下文”的元素和兄弟元素相互独立,也就是说,当进行层叠变化或渲染的时候,只需要考虑后代元素

(5)每个“层叠上下文”的元素是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠上下文的层叠顺序中(这点个人认为跟第二点表达的意思类似)

上一章我们讲了定位属性可以帮助创建“层叠上下文”,那么除了定位属性外还有哪些CSS属性或元素元素拥有层叠上下文呢?

(1)根层叠上下文

根元素默认拥有层叠上下文,这可能跟页面中如果没有定位元素的话,默认会定位到根元素是一个道理,我们可以近似认为根元素的position默认值为relative,这也就很好的解释了,为什么页面中所有元素至少处于一个“层叠结界”中。

(2)传统层叠上下文(z-index不为auto且生效)

在使用z-index属性的时候,我们需要注意该属性只能和某些CSS属性搭配使用才会生效,在CSS2.1的世界中,我们只需要注意z-index需要搭配定位元素使用即可,然而在CSS3中,还有一些其他属性也支持生成层叠上下文结界,等下我会列出这些属性。在上一章节中,我测试并验证了:z-index正值>z-index:0约等于z-index:auto>z-index负值。为什么我要说z-index:0约等于z-index:auto。两者的根本区别就在于是否会创建层叠上下文。z-index:auto是定位元素的默认属性,该元素依旧是一个普通元素,而z-index:0是一个显示声明,在生效的情况下会给当前元素创建层叠上下文,这两者在"层级别"的角度上讲是一样的,也就是他们的层叠水平相同(同级元素比较),但创建层叠上下文后会对内部元素产生较大的影响。干巴巴的说了一大堆还是不明白?我们用测试验证一下上面的说法。

来看下面两段代码产生的不同结果:

<div style="position:relative; z-index:auto;">
    <!-- 美女 -->
    <img src="1.jpg" style="position:absolute; z-index:2;">  
</div>
<div style="position:relative; z-index:auto;">
    <!-- 美景 -->
    <img src="2.jpg" style="position:relative; z-index:1;">  
</div>
 
<div style="position:relative; z-index:0;">
    <!-- 美女 -->
    <img src="1.jpg" style="position:absolute; z-index:2;">  
</div>
<div style="position:relative; z-index:0;">
    <!-- 美景 -->
    <img src="2.jpg" style="position:relative; z-index:1;">  
</div>

两段代码产生了完全不同的结果。当z-index:auto生效的时候,两张图片的父容器均为普通定位元素,因此图片的z-index的参照物是最近的“层叠结界”(可能是根层叠上下文),由于美女图的z-index>风景图的,因此遵循"谁大谁上"原则。而当z-index:0生效的时候,两张图片的父容器均创建了层叠上下文,父容器在层叠水平上是同级的(均为z-index:0),因此遵循"后来居上"原则,此时内部的z-index属于胳膊肘拧不过大腿的状态,看起来就“失效了”。

(3)CSS3中的层叠上下文

刚才提到了,CSS3中新增了一些可以直接创建层叠上下文的属性,在这里我标出我认为比较搞的属性,并罗列其他属性。CSS3的内容本章不多做展开,恕我直言,我也不会。

  • z-index值不为auto的flex项(父元素display:flex|inline-flex).
  • 元素的opacity值不是1.
  • 元素的transform值不是none.
  • 元素mix-blend-mode值不是normal.
  • 元素的filter值不是none.
  • 元素的isolation值是isolate.
  • will-change指定的属性值为上面任意一个。
  • 元素的-webkit-overflow-scrolling设为touch.

这里我单独拿出第二条说明一下,注意这里的说明是opacity不是1,在我们做颜色渐变的特效的时候,往往元素的初始状态是opacity为1,过渡到一个<1的值,然而这个变化会会使得元素的层级有意想不到的情况发生,因此需要注意在做透明度过度的时候尽量设置元素本身的opacity为0.99这样的近似值。

(4)层叠上下文与层叠顺序

上一章我在讲层叠顺序的时候给出了这样一张图,这里我们需要注意的是,只要能生成z-index:auto的CSS属性,就有可能会影响层叠顺序,除了比较好记的定位元素外,我们还需要注意CSS3新增的一些属性,尤其是我刚才提到的opacity不为1的属性,只要能让z-index:auto属性生效的元素,就会提升自身元素的层级,这是一个注意点,单独讲一下加深印象。

2.z-index负值理解与使用

z-index是支持负值的,在z-index负值生效的时候,该元素的层级在当前层叠上下文中仅比backgroud/border等装饰品的层级高一级,可以认为是“最低”的。通常我们需要某个元素部分隐藏的时候可以用到z-index:负值。在使用z-index的负值属性的时候,需要注意一个点,z-index属性会去找第一个层叠上下文元素作为层叠结界,因此我们在使用的时候要相当注意当前z-index生效的元素的层叠结界是谁。可以说,没有明确层叠结界的z-index都是耍流氓。(我说的明确不是浏览器明确,而是你自己要知道层叠结界在哪里,浏览器可不会犯糊涂)我们通过一个例子加深一下印象:

<!-- z-index负值 -->
<div class="box">
    <div class="content">我被隐藏了</div>
</div>
<style>
.box{
    width: 200px;
    height: 200px;
    background: rgb(255,255,0);
}
.content{
    width: 300px;
    height: 300px;
    background: rgb(0,255,255);
    position: relative;
    z-index: -1;
}
</style>

可以看到文字不见了,content元素的被box遮挡了一部分内容,这是因为两者的默认层叠结界都是根层叠结界,因此content的层级要比box的低,就被覆盖了。如果我们给box加上一个层叠结界呢?

<!-- z-index负值 -->
<div class="box">
    <div class="content">我被隐藏了</div>
</div>
<style>
.box{
    width: 200px;
    height: 200px;
    background: rgb(255,255,0);
    position: relative;
    z-index: 0;
}
.content{
    width: 300px;
    height: 300px;
    background: rgb(0,255,255);
    position: relative;
    z-index: -1;
}
</style>

可以看到结果已经完全不同了,此时content的z-index:-1找到了第一个层叠结界是box元素,因此不管z-index有多大的负值,都不可能超过这个结界,我们可以看到,content元素覆盖了box的背景色。

利用z-index负值可以隐藏元素的特性,我们可以完成可访问性隐藏,只需要层叠上下文内某一个父元素加个不透明的背景色就可以了,他与clip相比的优势是无需绝对定位,而他的不足之处就是不具有普遍适用性,需要其他元素配合进行隐藏,说白了,就是维护成本高了,别人不知道你为什么这样做。

本章关于z-index的内容就到这儿了,这里做个总结。

(1)任何元素都拥有自己的层叠规则,要找到某一元素在z轴上的位置,就要先找他的层叠结界。

(2)记住“谁大谁上”,“后来居上”的黄金法则。

(3)遇到元素隐藏问题,不放检查下层叠结界的设置是否合理。

下一章的内容是CSS强大的文本处理能力,感兴趣的同学可以点个关注。

不忘初心,方得始终

喜欢博主的童鞋可以扫描二维码加博主好友~ 也可以扫中间二维码入驻博主的粉丝群(708637831)~当然你也可以扫描二维码打赏并直接包养帅气的博主一枚。