堆叠

很多情况下定位元素,并不像流内元素一样从上到下,从左到右。很多时候会有重叠,这时候就会有谁在上面,谁在下面的情况。

z-index

  • 为定位元素指定在其 z 轴的上下级

  • 用一个整数表示,数值越大,越靠近用户

  • 初始值为 auto,可以为负数 、0 、正数

堆叠上下文

z-index 越大就一定在上面吗?比较元素不在一个堆叠上下文的时候,没法通过 z-index 属性值的大小进行比较。

形成堆叠上下文的条件:

  • Root 元素

  • z-index 值不为 auto 的定位元素

  • 设置了 CSS3 属性的元素,比如 opacity、transform、animation 等

绘制顺序

正每个堆叠上下文中,从下到上:

  1. 形成该上下文元素的 border 和 background

  2. z-index 为负值的子堆叠上下文

  3. 常规流中的块级元素非浮动子元素

  4. 非定位的浮动元素

  5. 常规流内非定位行级元素

  6. z-index 为 0 的子元素或者子堆叠上下文

  7. z-index 为 正数的子堆叠上下文

同一堆叠上下文内子元素的堆叠顺序

  1. 堆叠上下文的根元素

  2. 设置了 position 属性,并且 z-index 为负的元素及其子元素, z-index 值较大的元素置于较小元素之上,同等属性值的元素按照 html 中出现的先后顺序堆叠。

  3. 没有设置 position 的元素

  4. 设置了 position 属性,并且 z-index 属性为 auto 的元素。

  5. 设置了 position 属性,并且 z-index 属性为正值的元素。

不同堆叠上下文

  • 堆叠上下文可以嵌入其他堆叠上下文。

  • 每个堆叠上下文和他的统计上下文是独立的。

  • 堆叠上下文中子元素按照前述顺序摆放。

  • 堆叠上下文内部的子堆叠上下文的z-index只在父堆叠上下文中有意义。

事例

HTML文档中有三个div元素,每个div中存在一个span元素,三个span元素分别设置背景颜色为 red,green,以及blue。然后每个span都设置为position: absolute,三个span的位置稍微错开以便可以仔细观察它们之间的堆叠顺序。然后将第一个span元素的z-index设置为1,其他两个不设置。

元素的叠放顺序如下:

<div class="zindex-container">
    <div> //1
        <span class="red">Red</span> //6
    </div>
    <div> //2
        <span class="green">Green</span> //4
    </div>
    <div> //3
        <span class="blue">Blue</span> //5
    </div>
</div>
.zindex-container{
    position: relative;
    background: #ccc;
    padding: 150px;
}
.red,.green,.blue{
    position: absolute;
    width: 200px;
    height: 200px;
}
.red{
    top: 0;
    left: 0;
    background: red;
    z-index: 1;
}
.green{
    top: 50px;
    left: 50px;
    background: green;
}
.blue{
    top: 100px;
    left: 100px;
    background: blue;
}

尝试在 red 的父元素中,添加 CSS3 的 opacity 属性,让其形成堆叠上下文。第一个 div 形成了一个新的堆叠上下文,red span 成为了新的上下文中的第一个子元素。

.zindex-container > div:first-child {
  opacity: .99;
}

元素的叠放顺序如下:

<div class="zindex-container">
    <div> //1
        <span class="red">Red</span> //1.1
    </div>
    <div> //2
        <span class="green">Green</span> //4
    </div>
    <div> //3
        <span class="blue">Blue</span> //5
    </div>
</div>

参考