层叠式上下文

什么是层叠式上下文

MDN 上对层叠式上下文的解释为:css

The stacking context is a three-dimensional conceptualization of HTML elements along imaginary z-axis relative to the user, who is assumed to be facing the viewport or the webpage. HTML elements occupy this space in priority order based on element attributes.html

层叠上下文(stacking context)是 HTML 元素的三维概念,这些 HTML 元素在一条假想的相对于面向(电脑屏幕的)视窗或者网页的用户的 z 轴上延伸,HTML 元素依据其自身属性按照优先级顺序占用层叠上下文的空间。css3

简单来讲,正常状况下,网页上的内容都是一个个正常的排列,然而因为页面内容并无一个垂直方向的视角能够查看,因此,当页面上的内容发生重叠的时候,必定会有一个前后的顺序来呈现,而层叠式上下文就是解决这个问题的。web

CSS 2.1 规范中,每一个盒模型的位置是三维的,通常状况下咱们只能感知到页面上左右方向和上下方向分别对应的 X 轴和 Y 轴,感受不到垂直于电脑屏幕的 Z 轴,以下图所示:app

层叠顺序

前面咱们讲了元素发生重叠时要有一个前后的顺序来排列,那么不一样的元素之间就会有一个等级的比较(就是谁等级高谁在前面),那么怎么去断定的等级高呢,咱们一会儿就想到了 z-index 属性,的确,不少时候,z-index 能够影响元素的层叠等级,可是 z-index 只能在定位的元素上起做用,而层叠等级是在每一个元素中都存在的。wordpress

每一个元素的层叠顺序是由元素当前所属的层叠式上下文和元素自己的层叠等级来决定的。也就是说比较元素的层叠顺序,必须是在同一个层叠式上下文中进行比较,不然将毫无心义,具体的规则以下:flex

  1. 在同一个层叠式上下文中,层叠级别大的显示在上面,级别小的显示在下面。
  2. 在同一个层叠式上下文中,若是层叠级别相同,则按照它们在文档流中的顺序,写在后面的将覆盖前面的。
  3. 在不一样的层叠式上下文中,元素的显示顺序依据祖先的层叠级别来决定,与自身的层叠级别无关。

在 CSS2.1(不考虑CSS3)时期,层叠顺序遵循下面的图中所示的规则:this

上面须要注意的是:spa

  1. 位于最底层的 border/background 指的是层叠上下文元素的边框和背景色。
  2. 单纯从层叠水平上看, z-index:0 和 z-index:auto 是属于同一等级的,可是二者是有本质区别的。

如何造成层叠式上下文

前面讲了层叠顺序要在同一个层叠式上下文中进行比较,那么如何造成一个层叠式上下文呢? 如下是 MDN 上总结的造成层叠式上下文的条件:3d

  1. 根元素 (HTML),造成一个根级的上下文。
  2. 定位的元素(绝对/相对定位/fixed定位),z-index 值不为 auto 时。
  3. css3 中的一些属性:
    • z-index 值不为 auto 的 flex 项(父元素display:flex|inline-flex)。
    • 元素的 opacity 值不是1;
    • 元素的 transform 值 不是 none;
    • mix-blend-mode 属性值不为 normal 的元素;
    • filter值不为 none 的元素;
    • perspective值不为 none 的元素;
    • isolation 属性被设置为 isolate 的元素,
    • 在 will-change 中指定了任意 CSS 属性;
    • -webkit-overflow-scrolling 属性被设置 touch 的元素;

demo 时刻

定位与 z-index 值

<div class="box1">
  <p class="a">a盒子</p>
  <p class="b">b盒子</p>
</div>
<div class="box2">
  <p class="c">c盒子</p>
</div>
复制代码
p {
  position: absolute;
  font-size: 20px; 
  width: 100px;
  height: 100px;
}
.a {
  background-color: aqua; 
}
.b {
  background-color: pink; 
  top: 40px;  
  left: 40px;  
}
.c {
  background-color: beige;
  top: 80px;  
  left: 80px;  
}
复制代码

按上面代码,此时 a、b、c 三个盒子都发生了定位,可是它们的父盒子都没造成层叠式上下文,所以会按照文档流的顺序发生层叠,结果以下图:

evernotecid://7F04FEFC-BAE7-46E8-9645-3E736A89ACEB/appyinxiangcom/2486197/ENResource/p1178

接下来咱们进行一下改动,给 a、b、c 三个盒子分别加上 z-index 值,

.a {
  z-index: 3;  
}
.b {
  z-index: 2;  
}
.c {
  z-index: 1;  
}

复制代码

这时候,三个盒子自身都造成了层叠式上下文,可是它们的父盒子依旧没有造成层叠式上下文,因此它们是同属于一个层叠式上下文中,也就是根级,这时候它们的排列会按照各自的层叠等级进行排列,也就是 z-index 值大的在上面以下图所示:

接下来再进行一下改进,给它们的父元素分别加上如下属性:

div {
  position: relative;
}
.box1 {
  z-index: 1
}
.box2 {
  z-index: 2
}
复制代码

此时呢,两个 div 父元素都造成了一个层叠式上下文,那么 a、b 在同一个上下文中,按照自身的层叠等级进行排列,而 它们和 c 元素则处于不一样的层叠上下午呢中, 因此根据父级的 z-index 大小来肯定层级:

层叠顺序 demo

根据前面层叠顺序图中所示,咱们建立了如下demo:

.one{
      background: #4f6fc1;
      margin-left: 100px;
}
.two{
      float: left;
      background: #51cd8d;
      margin-top: -100px;
}
.three{
     display: inline-block;
     background: #9cd262;
     margin-left: -100px;
}
复制代码
<div class="one">one —— 块级元素</div>
<div class="two">two —— 浮动元素</div>
<div class="three">three —— inline/inline-block 元素</div>
复制代码

上图能够看出,层级关系为:行内块盒子(inline-block)> 浮动元素 > 块级元素。所以若是咱们想要盖住某一条线的话,不必定非得要用 display: relative,能够直接用 display: inline-block 就能够了。

接下来咱们再加入一个 z-idnex 为负值的盒子

.four{
  position: absolute;
  z-index: -1;
  background: #8874c1;
}
复制代码
<div class="four">four —— z-index为负值</div>
<div class="one">one —— 块级元素</div>
<div class="two">two —— 浮动元素</div>
<div class="three">three —— inline/inline-block 元素</div>
复制代码

能够看出此时,z-idnex 为负值的盒子层级最低,跟前面的层级图中所表示的相符合。

最后,咱们再加上 z-idnex 为 0 和正值的盒子。

.five{
     position: absolute;
     background: #d9ac4c;
     margin-top: -130px;
     margin-left: 50px;
}
.six{
    position: absolute;
    z-index: 1;
    background: #d93953;
    margin-top: -50px;
    margin-left: 150px;
}
复制代码
<div class="five">five —— z-index:auto/z-index:0</div>
 <div class="six">six —— z-index为正值</div>
复制代码

此时,5号盒子 z-index 值为 auto,可是却和 z-index 值为 0 同样的等级,可是二者本质上倒是不一样的,前面说过,z-index 值为 0 是建立了一个本身的层叠式上下文的,而值为 auto 却没有。

最后前面介绍的几个 CSS3 的属性所在的层叠等级是和 z-index:auto/z-index:0 是处在同一等级的,感兴趣的能够试一下。

参考

张鑫旭-《深刻理解CSS中的层叠上下文和层叠顺序》 MDN--The stacking context css层叠上下文【stacking context】和层叠顺序【stacking order】

相关文章
相关标签/搜索