前端面試之層疊上下文(z-index)

小諾哥發表於2019-02-21

什麼是層疊上下文

層疊上下文是HTML元素的三維概念,這些HTML元素在一條假想的相對於面向(電腦螢幕的)視窗或者網頁的使用者的z軸上延伸,HTML元素依據其自身屬性按照優先順序順序佔用層疊上下文的空間。

所以一個頁面中往往不僅僅只有一個層疊上下文(因為有很多種方式可以生成層疊上下文),在一個層疊上下文內,我們按照層疊水平的規則來堆疊元素。

我們可以把觸發層疊上下文的條件分為三大類:

預設建立層疊上下文

  • 根元素html

這就是為什麼,絕對定位元素在left/top等值定位的時候,如果沒有其他定位元素限制,會相對瀏覽器視窗定位的原因。

需要配合 z-index 觸發建立層疊上下文

  • z-index 值不為 "auto"的 絕對/相對/絕對定位,會建立層疊上下文
<style>
    * {
        margin: 0;
        padding: 0;
    }
    .container {
        background: pink;
        height: 100vh;
    }
    .box {
        width: 160px;
    }
    .box1 {
        position: relative;
        left: 0;
        top: 0;
        z-index: 1;
        background: blue;
        height: 160px;
    }
    .box2 {
        position: absolute;
        left: 0;
        top: 0;
        z-index: -1;
        background: gray;
        height: 180px;
    }
    .box3 {
        position: fixed;
        z-index: 0;
        background: greenyellow;
        left: 0;
        top: 0;
        height: 200px;
    }
    .box4 {
        height: 220px;
        background: orange;
    }
</style>
 <div class="container">
    <div class="box1 box">相對定位, z-index: 1</div>
    <div class="box2 box">絕對定位, z-index: -1</div>
    <div class="box3 box">固定定位, z-index: 0</div>
    <div class="box4 box">普通元素</div>
</div>
複製程式碼

前端面試之層疊上下文(z-index)

  • flex 項(父元素 display 為 flex|inline-flex),注意是子元素,不是父元素建立層疊上下文
<style>
* {
    margin: 0;
    padding: 0;
}
.box { display: flex; background: pink;}
.box > div { background-color: blue; z-index: 1; }    /* 此時該div是層疊上下文元素,同時z-index生效 */
.box > div > img {
    position: relative; z-index: -1; right: -150px;     /* 注意這裡是負值z-index */
}
</style>

 <div class="box">
    <div>
        <img src="mm.png">
    </div>
</div>
複製程式碼

flex 項(父元素 display 為 flex|inline-flex),注意是子元素,不是父元素建立層疊上下文

不需要配合 z-index 觸發建立層疊上下文

這種情況下,基本上都是由 CSS3 中新增的屬性來觸發的。

  • opacity 屬性值小於 1 的元素,會觸發z-index
<style>
    * {
        margin: 0;
        padding: 0;
    }

    .box { background-color: blue; opacity: 0.5;  }

    .box>img {
        position: relative;
        z-index: -1;
        right: -150px;
    }
</style>
 <div class="box">
    <img src="mm.png">
</div>
複製程式碼

opacity 屬性值小於 1 的元

  • transform 屬性值不為 "none"的元素
<style>
    * {
        margin: 0;
        padding: 0;
    }

    .box {
        background-color: blue;
        transform: rotate(15deg);
    }

    .box>img {
        position: relative;
        z-index: -1;
        right: -150px;
    }
</style>
<div class="box">
    <img src="mm.png">
</div>
複製程式碼

transform 屬性值不為

<style>
    * {
        margin: 0;
        padding: 0;
    }

    .box {
        background-color: blue;
        mix-blend-mode: darken;
    }

    .box>img {
        position: relative;
        z-index: -1;
        right: -150px;
    }
</style>
<div class="box">
    <img src="mm.png">
</div>
複製程式碼

mix-blend-mode 屬性值不為

<style>
    * {
        margin: 0;
        padding: 0;
    }

    .box {
        background-color: blue;
        perspective: 250px;
    }

    .box>img {
        position: relative;
        z-index: -1;
        right: -150px;
    }
</style>
 <div class="box">
    <img src="mm.png">
</div>
複製程式碼

perspective值不為“none”的元素

  • filter與層疊上下文
<style>
    * {
        margin: 0;
        padding: 0;
    }

    .box {
        background-color: blue;
        filter: blur(5px);
    }

    .box>img {
        position: relative;
        z-index: -1;
        right: -150px;
    }
</style>
 <div class="box">
    <img src="mm.png">
</div>
複製程式碼

filter

  • isolation 屬性被設定為 "isolate"的元素
  • 在 will-change 中指定了任意 CSS 屬性,即便你沒有直接指定這些屬性的值
  • -webkit-overflow-scrolling 屬性被設定 "touch"的元素

什麼是層疊水平

一個 DOM 元素,在不考慮層疊上下文的情況下,會按照層疊水平決定元素在 z 軸上的顯示順序,通俗易懂地講,不同的 DOM 元素組合在一起發生重疊的時候,它們的的顯示順序會遵循層疊水平的規則,而 z-index 是用來調整某個元素顯示順序,使該元素能夠上浮下沉。

7階層疊水平

- 在同一層疊上下文中,層疊水平才有意義
- z-index的優先順序最高
複製程式碼

比較兩個DOM元素顯示順序

  • 如果是在相同的層疊上下文,按照層疊水平的規則來顯示元素
  • 如果是在不同的層疊上下文中,先找到共同的祖先層疊上下文,然後比較共同層疊上下文下這個兩個元素所在的區域性層疊上下文的層疊水平。

推薦學習

note: 釋出有些匆忙,有誤地方後續訂正。

相關文章