1. 程式人生 > >我的z-index怎麼“失效”了?

我的z-index怎麼“失效”了?

大家有沒有遇到這樣的問題,給一個元素加上transform或者opacity等效果後,它的子元素的z-index就“失效了”?

這裡普及一個概念:stacking context,中文翻譯叫做“堆疊上下文”,這裡我們簡稱做“層”。

實際上,真正決定頁面上堆疊順序的並不是z-index,而是層。一個層就是頁面上Z軸的一個單位,並且頁面的Z軸並不是一維的,而是多維的,每一個層內部還可以包含多個層。
每層用各自的z-index值來比較排序(正值>0>auto(已定位)>auto(未定位)>負值)。 (已定位指position不為static,position為static的元素無法給z-index賦值)

我們來看下面這張圖:

這裡寫圖片描述

圖中DIV1有A和B兩個子元素,DIV2有C和D兩個子元素。
最終呈現在頁面上的效果如圖,堆疊順序從上到下依次是A,B,C,D。A會顯示在最上面。

這就像是棟房子,2樓的小矮子會位於1樓的大高個上面。

什麼?你不相信這個結果?那我們就來實驗一下。
我們先看例一:

<style> 
    div{position:abosolute; width:100px; height:100px;} 
</style>

<div id="A">
    <div id="B" style="background:green"
>
</div> </div> <div id="C" style="background:pink; left:20px; top:50px"></div>

這裡寫圖片描述

A和C的z-index都等於auto(預設值),它們就像是都在樓房的1樓,那應該怎麼確定堆疊順序呢?它們會按照文件的排列順序來決定堆疊順序,C在A的文件下面,所以會覆蓋A,也會覆蓋B。

如果我們給綠色box加上z-index:2 , 結果如例二:

<style> 
    div{position:abosolute; width:100px; height:100px;}
</style> <div id="A"> <div id="B" style="background:green; z-index:2"></div> </div> <div id="C" style="background:pink; left:20px; top:50px"></div>

這裡寫圖片描述

B的z-index=2後會在A內部產生新的堆疊上下文,就不能再按照文件順序來排列了。B會覆蓋C。(注意,A內其他z-index=auto的元素依然會被C覆蓋)

如果我們給A加上z-index=-1,會如何呢?來看例三:

<style> 
    div{position:abosolute; width:100px; height:100px;} 
</style>

<div id="A" style="z-index:-1">
    <div id="B" style="background:green; z-index:2"></div>
</div>
<div id="C" style="background:pink; left:20px; top:50px"></div>

這裡寫圖片描述

由於z-index=-1,此時的A就像是在負1樓,即使B的z-index=2也會被C覆蓋。

說到這裡,大家應該明白了怎麼判斷堆疊順序了。
有人會問,這些和一開始說的transform和opacity沒關係啊?

實際上,transform和opacity等特性,會和z-index一樣產生新的堆疊上下文。

MDN上說明了哪些情況會產生新的堆疊上下文:

the root element (HTML),
positioned (absolutely or relatively) with a z-index value other than “auto”,
a flex item with a z-index value other than “auto”,
elements with an opacity value less than 1,
elements with a transform value other than “none”,
elements with a mix-blend-mode value other than “normal”,
elements with isolation set to “isolate”, on mobile WebKit and Chrome 22+, position: fixed always creates a new stacking context, even when z-index is “auto”,
specifing any attribute above in will-change even you don’t write themselves directly