乐趣区

关于css:CSS层叠上下文层叠等级层叠顺序和zindex

一、层叠上下文

层叠上下文 (stacking context),是 HTML 中一个三维的概念。在 CSS2.1 标准中,每个盒模型的地位是三维的,别离是立体画布上的 X 轴,Y 轴以及示意层叠的 Z 轴。个别状况下,元素在页面上沿 X 轴 Y 轴平铺,咱们觉察不到它们在 Z 轴上的层叠关系。而一旦元素产生重叠,这时就能发现某个元素可能笼罩了另一个元素或者被另一个元素笼罩。
如果一个元素是层叠上下文元素,咱们能够了解为这个元素在 Z 轴上就“出人头地”,最终体现就是它离屏幕观察者更近。

你能够把层叠上下文元素了解为了解为该元素当了官,而其余非层叠上下文元素则能够了解为普通群众。但凡“当了官的元素”就比一般元素等级要高,也就是说元素在 Z 轴上更靠上,更凑近观察者。

二、层叠等级

层叠等级(stacking level,叫层叠级别 / 层叠程度也行),决定了同一个层叠上下文中元素在 z 轴上的显示程序。

比如说:处于层叠上下文中的元素,就像是元素当了官,等级天然比一般元素高。再设想一下,假如一个官员 A 是个省级领导,他上司有一个秘书 a -1,家里有一个保姆 a -2。另一个官员 B 是一个县级领导,他上司有一个秘书 b -1,家里有一个保姆 b -2。a- 1 和 b - 1 尽管都是秘书,然而你想一个省级领导的秘书和一个县级领导的秘书之间有可比性么?谁大谁小,谁高谁低高深莫测,所以基本没有比拟的意义。只有在 A 上司的 a -1、a- 2 以及 B 上司的 b -1、b- 2 中互相比拟大小高下才有意义。

分割下面说到的层叠上下文能够得出结论:
1、一般元素的层叠等级优先由其所在的层叠上下文决定。
2、层叠等级的比拟只有在以后层叠上下文元素中才有意义。不同层叠上下文中比拟层叠等级是没有意义的。

三、层叠程序

层叠程序 (stacking order) 示意元素产生层叠时依照特定的程序规定在 Z 轴上垂直显示。由此可见,后面所说的 层叠上下文 层叠等级 是一种概念,而这里的 层叠程序 是一种规定。

当元素产生层叠时,层叠程序遵循下面图中的规定。
这里值得注意的是:
1、左上角 ” 层叠上下文 background/border” 指的是层叠上下文元素的背景和边框。
2、inline/inline-block 元素的层叠程序要高于 block(块级)/float(浮动)元素。
3、单纯思考层叠程序,z-index: auto 和 z -index: 0 在同一层级,但这两个属性值自身是有基本区别的。

为什么 inline/inline-block 元素的层叠程序要高于 block(块级)/float(浮动)元素?
其实很简略,像 border/background 属于装璜元素的属性,浮动和块级元素个别用来页面布局,而网页设计之初最重要的就是文字内容,所以在产生层叠时会优先显示文字内容,保障其不被笼罩。

四、如何产生“层叠上下文”

后面说了那么多,到底如何产生层叠上下文呢?如何让一个元素变成层叠上下文元素呢?
其实,层叠上下文也基本上是有一些特定的 CSS 属性创立的,个别有 3 种办法:
1、HTML 中的根元素 <html></html> 自身就具备层叠上下文,称为“根层叠上下文”。
2、一般元素设置 position 属性为非 static 值并设置 z -index 属性为具体数值,产生层叠上下文。
3、CSS3 中的新属性也能够产生层叠上下文。

栗子 1:

有两个 div,p.a、p.b 被包裹在一个 div 里,p.c 被包裹在另一个 div 里,只为.a、.b、.c 设置 position 和 z -index 属性。

<style>
     div {  
        position: relative;  
        width: 100px;  
        height: 100px;  
      }  
      p {  
        position: absolute;  
        font-size: 20px;  
        width: 100px;  
        height: 100px;  
      }  
      .a {  
        background-color: pink;  
        z-index: 1;  
      }  
      .b {  
        background-color: yellow;  
        z-index: 2;  
        top: 20px;  
        left: 20px;  
      }  
      .c {  
        background-color: blue;  
        z-index: 3;  
        top: -40px;  
        left: 40px;  
      }
</style>
<div>  
  <p class="a">a</p>  
  <p class="b">b</p>  
</div> 
<div>  
  <p class="c">c</p>  
</div>  

成果:

因为 p.a、p.b、p.c 三个的父元素 div 都没有设置 z -index,所以不会产生层叠上下文,所以.a、.b、.c 都处于由 <html></html> 标签产生的“根层叠上下文”中,属于同一个层叠上下文,此时谁的 z -index 值大,谁在下面。

栗子 2:

有两个 div,p.a、p.b 被包裹在一个 div 里,p.c 被包裹在另一个 div 里,同时为两个 div 和.a、.b、.c 设置 position 和 z -index 属性。

<style>
     div {  
        position: relative;  
        width: 100px;  
        height: 100px;  
      }  
      .box1 {z-index: 2;}
      .box2 {z-index: 1;}
      p {  
        position: absolute;  
        font-size: 20px;  
        width: 100px;  
        height: 100px;  
      }  
      .a {  
        background-color: pink;  
        z-index: 1;  
        z-index: 100;
      }  
      .b {  
        background-color: yellow;  
        z-index: 2;  
        top: 20px;  
        left: 20px;
        z-index: 200;  
      }  
      .c {  
        background-color: blue;  
        z-index: 3;  
        top: -40px;  
        left: 40px;  
        z-index: 999;
      }
    </style>
<div class="box1">
    <p class="a">a</p>
    <p class="b">b</p>
</div>
<div class="box2">
    <p class="c">c</p>
</div>

成果:

尽管 p.c 元素的 z -index 值为 999,远大于 p.a 和 p.b 的 z -index 值,然而因为 p.a、p.b 的父元素 div.box1 产生的层叠上下文的 z -index 的值为 2,p.c 的父元素 div.box2 所产生的层叠上下文的 z -index 值为 1,所以 p.c 永远在 p.a 和 p.b 上面。
另外,因为 p.a 和 p.b 这两个元素都在父元素 div.box1 产生的层叠上下文中,所以谁的 z -index 值大,谁在下面。

栗子 3:

有两个 div,div.box1 内有 div.child1,div.box2 内有 div.child2,来看一看.box1/.box2 的 z -index 属性值别离为 auto 和 0 时,.child1 和 child2 的层级有什么不同。

<style>
      .box1, .box2 {
        position: relative;
        z-index: auto;
        color:#333;
      }
      .child1 {
        width: 200px;
        height: 100px;
        background: orange;
        position: absolute;
        top: 0;
        left: 0;
        z-index: 2;
      }
      .child2 {
        width: 100px;
        height: 200px;
        background: pink;
        position: absolute;
        top: 20px;
        left: 0;
        z-index: 1;
      }
    </style>
<div class="box1">
  <div class="child1">child1</div>
</div>
<div class="box2">
  <div class="child2">child2</div>
</div>
  • .box1/.box2 的 z -index=auto 时成果:
  • .box1/.box2 的 z -index= 0 时成果:

1、.box1/.box2 尽管设置了 position: relative,然而 z -index: auto 的状况下,这两个 div 还是一般元素,并没有产生层叠上下文。所以,child1/.child2 属于 <html></html> 元素的“根层叠上下文”中,此时,谁的 z -index 值大,谁在下面。
2、而把.box1/.box2 的 z -index 属性值改为 0,最终后果齐全相同。这时.child2 笼罩在了.child1 下面。起因是什么呢?因为设置 z -index: 0 后,.box1/.box2 产生了各自的层叠上下文,这时候要比拟.child1/.child2 的层叠关系齐全由父元素.box1/.box2 的层叠关系决定。然而.box1/.box2 的 z -index 值都为 0,都是块级元素(所以它们的层叠等级,层叠程序是雷同的),这种状况下,在 DOM 构造中前面的笼罩后面的,所以.child2 就在下面。

五、CSS3 中的属性对层叠上下文的影响

CSS3 中呈现了很多新属性,其中一些属性对层叠上下文也产生了很大的影响。如下:

父元素的 display 属性值为 flex|inline-flex,子元素 z -index 属性值不为 auto 的时候,子元素为层叠上下文元素;
元素的 opacity 属性值不是 1;
元素的 transform 属性值不是 none;
元素 mix-blend-mode 属性值不是 normal;
元素的 filter 属性值不是 none;
元素的 isolation 属性值是 isolate;
will-change指定的属性值为下面任意一个;
元素的 -webkit-overflow-scrolling 属性值设置为 touch。

CSS3 中,元素属性满足以上条件之一,就会产生层叠上下文。咱们用第 1 条来做一个简略的解释阐明。

栗子 4:

栗子有三个层级:div.box > div.parent > div.child
咱们来看一下,给 div.box 设置 CSS3 属性 display=flex 对层级有什么影响。

<style>
     .box { }
     .parent {
        width: 200px;
        height: 100px;
        background: yellow;
        /* 尽管设置了 z -index,然而没有设置 position,z-index 有效,.parent 还是一般元素,没有产生层叠上下文 */
        z-index: 1;
      }
      .child {
        width: 100px;
        height: 200px;
        background: purple;
        position: relative;
        z-index: -1;
      }
</style>
<div class="box">
  <div class="parent">
    parent
    <div class="child">child</div>
  </div>
</div>

1、.parent 设置了 z -index 属性值,然而没有设置 position 属性,z-index 有效,所以没有产生层叠上下文,.parent 还是一般的块级元素。此时,在层叠程序规定中,z-index 值小于 0 的.child 会被一般的 block 块级元素.parent 笼罩。
2、当给.box 设置 display: flex 时,.parent 就变成层叠上下文元素,依据层叠程序规定,层叠上下文元素的 background/border 的层叠等级小于 z -index 值小于 0 的元素的层叠等级,所以 z -index 值为 - 1 的.child 在.parent 下面。

总结:

下面说了那么多,可能你还是有点懵。这么多概念规定,来点最理论的,有没有一个“套路”当遇到元素层叠时,能很清晰地判断出他们谁在上谁在下呢?答案是——必定有啊!

1、首先先看要比拟的两个元素是否处于同一个层叠上下文中:
      1.1 如果是,谁的层叠等级大,谁在下面(怎么判断层叠等级大小呢?——看“层叠程序”图)。
      1.2 如果两个元素不在对立层叠上下文中,请先比拟他们所处的层叠上下文的层叠等级。
2、当两个元素层叠等级雷同、层叠程序雷同时,在 DOM 构造中前面的元素层叠等级在后面元素之上。

退出移动版