z-index在日常開發中算是一個比較常用的樣式,一般理解就是設置標簽在z軸先後順序,z-index值大的顯示在最前面,小的則會被遮擋,是的,z-index的實際作用就是這樣。
但是你真的了解z-index嗎?你知道它有什麼特性嗎?這裡先拋出幾個名詞:“層疊順序(stacking order)”,“層疊上下文(stacking context)”,“層疊水平(stacking level)”。
先說一下z-index的基本用法:
z-index
可以設置成三個值:
auto
,默認值。當設置為auto
的時候,當前元素的層疊級數是0,同時這個盒不會創建新的層級上下文(除非是根元素,即<html>
);<integer>
。指示層疊級數,可以使負值,同時無論是什麼值,都會創建一個新的層疊上下文;inherit
。父元素繼承 z-index只在定位元素中起作用,舉栗子:
<style> #box1{ background: blue; width: 200px; height: 200px; } #box2{ background: yellow; width: 200px; height: 200px; margin-top:-100px; } </style> <div id="box1"></div> <div id="box2"></div>
我們希望box1要顯示在box2上面,可能這時候有同學會說,給box1加一個z-index大於0的值就可以了,這樣是不對的,如圖:
box2遮擋了box1,即使box1設置z-index值再大也白搭,前面說了z-index只在定位元素(position=static除外,因為元素默認就是static,相當於沒用position樣式)中作用,也是就z-index要配合position一起使用。感興趣的可以親自驗證一下,這裡只拋磚引玉。
層疊順序對絕對元素的Z軸順序
層疊順序其實不是z-index獨有的,每個元素都有層疊順序,元素渲染的先後順序跟它有很大關系,總之當元素發生層疊時,元素的層級高的會優先顯示在上面,層級一樣的則會根據dom的先後順序進行渲染,後面的會覆蓋前面的。文字再多可能也沒有一張圖來的直接,下面這張圖是“七階層疊水平”(網上盜的,很經典的一張圖)
再舉個栗子,這裡還是拿剛才那個栗子來說,在不用z-index的前提下,利用css層疊順序解決遮擋問題,代碼修改如下
<style> #box1{ background: blue; width: 200px; height: 200px; display:inline-block; } #box2{ background: yellow; width: 200px; height: 200px; margin-top:-100px; } </style> <div id="box1"></div> <div id="box2"></div>
這裡只做了細微的修改,就是給box1加了一個display:inline-block;的樣式,這裡解釋一下,首先box1和box2發生了層疊,然後box默認為塊級元素,即display:block,從七階圖中看出,display:block的元素的層疊水平低於display:inline-block的元素,所以浏覽器就將box2渲染到box1上面,如圖:
靈活的運用七階圖可以讓你的代碼盡可能的減少z-index的使用。因為多個人開發同一個系統,如果過多的用z-index,很有可能會出現沖突,即遮擋問題,一般來說z-index使用10以內的數值就足夠了。
重點:層疊上下文
先說一下如果創建層疊上下文,css創建層疊上下文的方法有很多,但是常用的也就夠那麼幾種
1、定位元素中z-index不等於auto的會為該元素創建層疊上下文
2、html根元素默認會創建層疊上下文(這是一個特例,知道就行)
3、元素的opacity不等於1會創建層疊上下文
4、元素的transform不等於none會創建層疊上下文
還有其它方式創建層疊上下文,這裡就不做介紹了,上面四中是開發中常用到的。
那麼知道怎麼創建層疊上下文之後,問題的關鍵來了,層疊上下文有什麼用呢?
這裡一定要結合前面那張七階圖,最下面那一層便background是建立在層疊上下文的基礎上的,也就是說在層疊上下文中,所有的元素都會渲染在背景和邊框上面;在block盒子、float盒子等不存在層級上下文的元素中,子元素設置z-index為負值的時候,那麼子元素會被父元素遮擋。說了可能不太好理解,舉個栗子消化一下:
<style> #box1{ position: relative; width: 200px; height: 200px; background: blue; } #box2{ position: relative; z-index:-1; width: 100px; height: 100px; background: yellow; } </style> <div id="box1"> <div id="box2"></div> </div>
這裡,box並沒有創建層疊上下文,當子元素box2設置z-index:-1時,box2所在的層疊上下文是根元素,即html根標簽,根據七階圖可以看出,box2會渲染在html標簽上面,普通盒子box1(z-index:auto)下面,所以box2被遮擋了。如圖所示:
那麼怎麼解決這個問題呢?相信大家已經知道這裡該怎麼處理了吧,是的,為box1建立一個層疊上下文,那麼box1中的元素無論z-index是負的多少,都會顯示在box1的背景之上,如圖:
這裡我用了前面說的的第一種方式去創建層疊上下文,即定位元素中z-index不為auto的元素會建立層疊上下文,可能有的同學開始納悶了,box1的z-index小於box2的z-index,為什麼box2缺顯示在box1的上面呢?呵呵,這正對應了七階圖的層疊水平的關系,不明白的再仔細揣摩一下七階圖。
· 層疊水平僅在直接父級層疊上下文中進行,即層疊上下文A中的子元素的層疊水平不會和另一個層疊上下文中的子元素進行比較。舉個例子
<style> #box1{ z-index: 10; position: relative; width: 200px; height: 200px; background: green; } #box1_1{ position: relative; z-index: 100; width: 100px; height: 100px; background: blue; } #box2{ position: relative; z-index: 11; width: 200px; height: 200px; background: red; margin-top: -150px; } </style> <div id="box1"> <div id="box1_1"> </div> </div> <div id="box2"> </div>
層疊上下文box1中的子元素box2設置z-index為100,而層疊上下文box2的z-index只有11,而實際的渲染效果卻是,box2在box1和box1_1的上面,這就應了上面那就話,層疊水平僅在元素的第一個父級層疊上下文中進行,即層疊上下文A中的子元素的層疊水平不會和另一個層疊上下文中的子元素進行比較,也就是活box1_1的z-index對於他的父級層疊上下文之外的元素沒有任何影響。這裡box2和box1在同一個層疊上下文中(html根元素會默認創建層疊上下文),所以它們兩個會進行層疊水平的比較,box2的z-index大於box1的z-index,所以我們看到的也就是下面這樣,box2遮擋了box1,不在乎box1中的子元素z-index是多少,如圖:
這裡我對z-index的理解也就講述完畢了,大概就說了以下這幾點內容:
1、z-index僅在定位元素(position不等於static)中有效
2、七階層疊水平圖
3、z-index層疊水平的比較僅限於父級層疊上下文中
其次需要注意以下幾點:
1、在開發中盡量避免層疊上下文的多層嵌套,因為層疊上下文嵌套過多的話容易產生混亂,如果對層疊上下文理解不夠的話是不好把控的。
2、非浮層元素(對話框等)盡量不要用z-index(通過層疊順序或者dom順序或者通過層疊上下文進行處理)
3、z-index設置數值時盡量用個位數
用了一晚上的時間整理了這篇文章,就連我自己對z-index也有了更加深刻的理解,希望對你也有幫助。如有錯誤 歡迎指正