今天話題是由z-index的偶然失效,引發的一系列問題。
一、序
從定義上看z-index真的是個很簡單的屬性,就是描述元素的層疊順序,但是有時間我們會發現z-index並不會起作用。這時候我們就需要好好的理解一下z-index背後的問題。
二、拋開position和z-index
我們多知道position的預設值為static,z-index的預設值為auto。當我們拋開position和z-index的設定,我們會發現層疊順序就是html元素的順序,但是不要忘記還有float和display。這裡我通過一個例子:
div.item1 inline-block
div.item2 float
div.item3 block
複製程式碼
從上面的結構我們可以知道層疊順序由大到小為inline-block(inline也是一樣),flaot,block。這裡只用了幾個常用的作比較,其他的你們也可以嘗試嘗試。
三、設定position
當position進來搞事情的時候,這就稍微有點複雜了。首先你要記住的:
- 當元素設定position為absolute,relative或者fixed,它們的層疊順序大於position為static的。
但是這裡又有很多細節問題,例如:當我們的dom結構多次巢狀時:
div.item1 A
div.child1 C
div.item2 B
複製程式碼
.item1 {
background: red;
.child1 {
position: absolute;
top: 100px;
left: 150px;
background: blue;
}
}
.item2 {
background: rgb(200,10,200);
}
複製程式碼
由上面的結論,我們知道當元素設定position不為static時,它的層疊順序比position為static的元素大(這裡我暫且用大來表示離使用者越近,詞窮-_-)。但是我們知道position中的absolute的規則:
- absolute 定位是相對於 static 定位以外的第一個父元素進行定位【這裡原先我也理解錯了,謝謝路過的大神^_^】
所以這裡就讓我們很鬱悶了,是吧?當我們的dom結構很複雜的時候,你突然來個positioned(position不為static)元素,可能就出現了不可控的情況。而實際上我們理想的情況是什麼?拿上面的例子說,既然C是A的子元素,那麼C的層疊順序就不應該大於比A層疊順序大的同級元素(這的確是你想要的。)
對於這種情況,我們只採用position的話,只能把A的同級和上級元素設定為positioned。
四、該z-index出場了
首先我們多知道,z-index真的是一個很單純的屬性,單純到賦值多沒有什麼花樣。但是我們通常多會用錯他。他正確的使用場景:
- 使用z-index的元素必須是positioned。
那麼我們再來看上面的需求,我們可以通過這樣的設定實現:
.item1 {
position: relative;
z-index: -1;
}
複製程式碼
這裡有人會這樣想:B的預設z-index為auto,而你設定了A的z-index的為-1,當然C不會再覆蓋B咯。但是真的是這樣嗎?
這時,你可以設定一下C的z-index,可以設定一個很大很大的值。但是並不會起作用,所以這裡我們要引入一個新的概念--層疊上下文(stacking context)
五、層疊上下文(stacking context)
對於層疊上下文的概念,我相信看了上面的例子,你應該知道上面意思,可能表達還有點詞窮。大白話就是:子元素要看設定層疊上下文的父元素的臉色行事了。其實說到層疊上下文,這裡我們要意識到一點,如果你的元素不是positioned,可能談層疊上下文就有點不靠譜了。
為什麼我會說這句話,現在我們知道z-index的設定依賴於positioned,而你如果不設定positioned,單純的html先後順序,並不會給我們帶來太大的困擾。
產生層疊上下文的情況:(下列多是基於positioned)
- 設定z-index不為auto;(所以0與auto是有區別的)
- opacity不為1;
- CSS3新出的屬性對層疊上下文產生了影響,例如transform不為none。還有其他的不常用的,我就不羅列了。
六、總結
到這裡我們可以總結一下考慮層疊順序的因素:
- html元素的排列順序
- display與float
- position
- z-index的使用
- 層疊上下文的產生
到這裡如果你還是很疑惑的話,我表示很抱歉。這裡送上兩篇參考的文章:
喜歡本文的小夥伴們,歡迎關注我的訂閱號超愛敲程式碼,檢視更多內容.