有关层叠上下文和层叠顺序的理解

有关层叠上下文和层叠顺序的理解

在网页中的内容发生层叠的时候,一定有前后的层叠顺序产生(如下),所以我们这就需要我们理解css里的层叠上下文和层叠顺序。

一、层叠上下文

层叠上下文,英文称作”stacking context”. 是HTML中的一个三维的概念。如果一个元素含有层叠上下文,我们可以理解为这个元素在z轴上有较高等级。

那么z轴是什么呢?

在CSS2.1规范中,每个盒模型的位置是三维的,分别是平面画布上的X轴Y轴以及表示层叠的Z轴。一般情况下,元素在页面上沿X轴Y轴平铺,我们察觉不到它们在Z轴上的层叠关系。而一旦元素发生堆叠,这时就能发现某个元素可能覆盖了另一个元素或者被另一个元素覆盖。

如果一个元素含有层叠上下文,(也就是说它是层叠上下文元素),我们可以理解为这个元素在Z轴上就“高人一等”,最终表现就是它离屏幕观察者更近。

换句话说,页面中的元素有了层叠上下文,就等同于网页中元素级别更高,离我们用户更近了。

二、层叠水平

“层叠水平”英文称作”stacking level”(也有翻译为“层叠等级”),它决定了同一个层叠上下文中元素在z轴上的显示顺序。

所有的元素都有层叠水平,包括“层叠上下文元素”,层叠上下文元素的层叠水平可以理解为官员的职级,1品2品,县长省长之类。然后,对于普通元素的层叠水平,我们的探讨仅仅局限在当前层叠上下文元素中。为什么呢?

假设省长下面有1级下属和2级下属,且1级下属的等级高于2级;同样县长下也有1级下属和2级下属,所以即使省长的2级下属也是高于县长的1级下属的。类似地,因为层叠上下文已经比普通元素的级别要高,这时候即使普通元素的层叠水平高于层叠上下文的层叠水平也无济于事。

结论:普通元素的层叠水平优先由其层叠上下文决定,因此,层叠水平的比较只有在当前层叠上下文元素中才有意义。不同层叠上下文中比较层叠水平是没有意义的。

三、创建层叠上下文

创建的3种途径:

  1. 根层叠上下文:HTML中的根元素“本身具有层叠上下文,称为“根层叠上下文”。
  2. 定位元素与传统层叠上下文:普通元素设置position属性为static值并设置z-index属性为具体数值,产生层叠上下文。
  3. CSS3中的新属性也可以产生层叠上下文(在本文末尾会写出)

需要注意的层叠上下文特性:
– 层叠上下文的层叠水平要比普通元素高;
– 层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的层叠上下文。
– 每个层叠上下文是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠上下文的层叠顺序中。

创建途径2的代码示例:

a、b、c处于不同的层叠上下文中,所以根据父级的z-index大小来确定层级。在线预览地址: https://codepen.io/XingTeng/pen/xoMedL

<body>
  <div class="box1">
    <p class="a">a</p>
    <p class="b">b</p>
  </div>

  <div class="box2">
    <p class="c">c</p>
  </div>
</body>

css:

.box1,
.box2{
    width: 100px;
    height: 100px;
    position: relative;
}
.box1 {
  z-index: 2;
}
.box2 {
  z-index: 1;
}
p {
  position: absolute;
  font-size: 20px;
  width: 100px;
  height: 100px;
  color: white;
}
.a {
  background-color: blue;
  z-index: 100;
}
.b {
  background-color: green;
  top: 20px;
  left: 20px;
  z-index: 200;
}
.c {
  background-color: red;
  top: -20px;
  left: 40px;
  z-index: 999;
}

box元素原本为普通元素,但通过设置position属性为static值并设置z-index属性为具体数值,产生层叠上下文。虽然c元素的z-index值为999,大于abz-index值,但是由于ab的父元素div.box1z-index的值为2,c的父元素div.box2的层叠上下文的z-index值为1,所以c永远在ab下面。

四、层叠顺序

“层叠顺序”英文称作”stacking order”. 表示元素发生层叠时候有着特定的垂直显示顺序,注意,这里跟上面两个不一样,上面的层叠上下文和层叠水平是概念,而这里的层叠顺序是规则

css2时代的层叠顺序:

层叠顺序表

注意点:
1. 位于最低水平的border/background指的是层叠上下文元素的边框和背景。

  1. 原图没有呈现inline-block的层叠顺序,实际上,inline-block和inline水平元素是同等level级别。

  2. z-index:0实际上和z-index:auto单纯从层叠水平上看,是可以看成是一样的。注意这里的措辞——“单纯从层叠水平上看”,实际上,两者在层叠上下文领域有着根本性的差异。

  3. 内联元素的层叠顺序要比浮动元素和块状元素都高。 原因:border/background一般为装饰属性,而浮动和块状元素一般用作布局,而内联元素都是内容。网页中最重要的是内容。因此,一定要让内容的层叠顺序相当高,当发生层叠是很好,重要的文字啊图片内容可以优先暴露在屏幕上。

五、有关层叠问题的“套路”

当元素发生层叠的时候,我们可以根据下面2条准则进行判断:
1. 如果在同一个层叠上下文领域,当具有明显的层叠水平标示的时候,如识别的z-index值,层叠水平值大的那一个覆盖小的那一个。

  1. 当元素的层叠水平一致、层叠顺序相同的时候,在DOM流中处于后面的元素会覆盖前面的元素。

代码示例:

<div class="box3">
    <div class="d">d</div>
  </div>

  <div class="box4">
    <div class="e">e</div>
  </div>

css:

.box3,
.box4 {
  width: 100px;
  height: 100px;
  position: relative;
  z-index: auto;
  left: 300px;
  top: -180px;
}

.d {
    width: 200px;
    height: 100px;
    background: #168bf5;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
}

.e {
    width: 100px;
    height: 150px;
    background: #32c292;
    position: absolute;
    top: -50px;
    left: 0;
    z-index: 1;
}

box3和box4虽然设置了position: relative,但是z-index: auto的情况下,这两个div还是普通元素,并没有产生层叠上下文。所以,d和e属于“元素的“根层叠上下文”中,此时,谁的z-index值大,谁在上面

六、css3下的新时代的层叠上下文

CSS3的出现除了带来了新属性,同时还对层叠上下文产生新的影响。

如下:

  1. z-index值不为autoflex项(父元素display:flex|inline-flex),子元素z-index属性值不为auto的时候,子元素为层叠上下文元素;
  2. 元素的opacity值不是1.
  3. 元素的transform值不是none.
  4. 元素mix-blend-mode值不是normal.
  5. 元素的filter值不是none.
  6. 元素的isolation值是isolate.
  7. will-change指定的属性值为上面任意一个。
  8. 元素的-webkit-overflow-scrolling设为touch.

以第一条为例:

<div class="box5">
    <div class="f">f
        <div class="g">g</div>
    </div>
</div>
.f {
  width: 200px;
  height: 100px;
  background: #cac719;
  /* 虽然设置了z-index,但是没有设置box5的position,z-index无效,.f还是普通元素,没有产生层叠上下文 */
  z-index: 1;
}

.g {
  width: 100px;
  height: 200px;
  background: #e767e1;
  position: relative;
  z-index: -1;
}

f在g上方显示了。我们查找层叠顺序图可以找到,负值z-index的层叠顺序在block水平元素的下面,而黄色背景div元素是个普通的block元素,于是z-index小于0的g会被f覆盖。

上面的例子,如果修改.box5的属性,其余DOM不变:

.box5 {
    display: flex;
}

当给.box5设置display: flex时,.f就变成层叠上下文元素,根据层叠顺序规则,层叠上下文元素的background/border的层叠等级小于z-index值小于0的元素的层叠等级,所以z-index值为-1.g.f上面。

总结

本文整理了关于层叠方面的一些基本知识点,一些细节的应用还需要平时的积累。

参考资料:

张鑫旭-《深入理解CSS中的层叠上下文和层叠顺序》

AMInInsist-《CSS 中的z-index属性》

发表评论

电子邮件地址不会被公开。 必填项已用*标注