CSS z-index 探討

一、背景

你有沒有在項目代碼中遇到這樣一種情況,由于代碼是小組協(xié)同開發(fā),每個人所寫的部分都不一樣,但是會組合到一起。而每個人的CSS中的樣式也是肯定不一樣的,那么對于定位元素,層疊順序可能會影響一個組件在頁面中的顯示情況。于是大家都會設定z-index來使自己寫的小組件一定是在某種情況下可展示的,但是自己無論怎樣調整z-index的值都無法達到效果。也就是說,雖然我們把當前的某一個元素的z-index設為了9999999...,但還是無法達到我們的效果,那么我們就進入了一個誤區(qū)。

比如以下demo:

.stacking-context1 {
    height: 200px;
    width: 100%;
    background-color: green;
    position: absolute;
    z-index: 1;
}
.stacking-context2 {
    height: 100px;
    width: 100%;
    background-color: blue;
    position: absolute;
    z-index: 999;
}
.stacking-context3 {
    height: 200px;
    width: 100%;
    background-color: pink;
    position: absolute;
    z-index: 2;
}

<div class="stacking-context1">
        z-index: 1
        <div class="stacking-context2">z-index: 999</div>
</div>
<div class="stacking-context3">z-index: 2</div>

按照我們的預想,現(xiàn)在的堆疊順序應該為:

z-index-test1

實際為:


z-index-test2

那為何會出現(xiàn)這種情況呢?

二、探討

當我們有一個 <div id="parent"> 包著一群 <div class="child"> 元素時,它們的堆疊順序通常會一起被移動(從父原則),這整個群組的順序就是 stacking context,要完全理解 stacking context 我們就必須要參透 z-index 是怎麼排序 stacking order。
每一個 stacking context 有一個唯一的 HTML 元素當作其根元素,當一個新的 stacking context 或者我們翻作堆疊環(huán)境被建立在一個元素上時,這個堆疊環(huán)境就會控管它內部的子元素的順序 stacking order,意思是如果其中一個元素在這個堆疊環(huán)境中順序被排在最底下,那它就完全沒機會出現(xiàn)在另外一個元素排位較高的堆疊環(huán)境前面,就算他的 z-index 設成 9999999。
從另外一個角度來說,每一個被設定 position 的元素除了自己的 stacking order 另外如果內部還有子元素,就會有一個 stacking context 來管制底下的元素。
要建立一個堆疊環(huán)境 stacking context有下面三者方式,只要使用其一即可:
1.當元素是網(wǎng)頁文件的根元素通常就是 <html>
2.當元素被設定 position 除了 static 以外的值,然後 z-index 設定為除了 auto 以外的值
3.當元素設定了 opacity 且值小於 1
上面提到的三種方式中,前兩者大部分的開發(fā)者都知道,即使他們不懂原理但還是會使用。第三種方式除了 w3c 規(guī)範,大多開發(fā)者都不曾提到。
此外除了 opacity 另外一些新的屬性像是 transforms, filters, css-regions, paged media 等等都會產生 stacking context。
還有當 css 屬性需要在超出螢幕的地方渲染,他也會產生一個 stacking context。
來源:https://andyyou.github.io/2016/03/03/z-index/

如何決定元素在堆疊環(huán)境中的位置?

在單一的堆疊環(huán)境從最下面(后)到上面(前)規(guī)則如下

  1. 執(zhí)行堆疊的根元素。
  2. 有設定 position 且 z-index 為負數(shù)的元素和它們的子元素,-1 在 -2 前面。
  3. 沒有設定 position 的元素,一般元素。
  4. 有設定 position 且 z-index 為 auto,設定 opacity 小于 1 和其他 transforms 等屬性也在此列。
  5. 有設定 position 且 z-index 為正數(shù)。
    都一樣的時候就比文件中代碼出現(xiàn)的先后順序,后出現(xiàn)的出現(xiàn)在上面。

因此,當我們的某個元素已經創(chuàng)建了“堆疊上下文環(huán)境”(stacking contetxt),那么它里面的元素再怎么設置z-index也不可能影響它的父元素所在的堆疊上下文環(huán)境中的順序,也就是說他只能在他的按順序已創(chuàng)建了堆疊上下文環(huán)境的元素中進行比較,而他的父元素的堆疊順序決定了他在父元素所處環(huán)境中的位置。
也就是說當我們把z-index設得很大卻無濟于事的時候,很可能該元素的上層元素已經具備stacking context了。

所以,為了達到我們在demo中想要的效果其實很簡單,只要把stacking-context1的z-index改為3就行了。

.stacking-context1 {
    height: 200px;
    width: 100%;
    background-color: green;
    position: absolute;
    z-index: 3;
}
.stacking-context2 {
    height: 100px;
    width: 100%;
    background-color: blue;
    position: absolute;
    z-index: 999;
}
.stacking-context3 {
    height: 200px;
    width: 100%;
    background-color: pink;
    position: absolute;
    z-index: 2;
}

<div class="stacking-context1">
        z-index: 1
        <div class="stacking-context2">z-index: 999</div>
</div>
<div class="stacking-context3">z-index: 2</div>
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容