z-index是我們以前相對比較經常使用的一個語法了,看起來比較簡單的樣子,實際上還真不難,由於這東西跟以前講的vertical-align不同,這個比較符合我們的認知。css
好了,不廢話,開始我們的正式話題。html
首先呢?我們先要了解一下層疊上下文(stack context)是什麼呢,其實通俗來說,就是你看電腦的這個方向的一個顯示順序,好比說,桌子上有一大堆紙,你對着它看的話,每一張紙,實際上你就能夠理解爲一個層疊上下文中的一個層疊順序(stack level),你能看到的,每每是最靠前的那幾張紙,後面的都被遮擋住了。前端
那麼,首先最簡單的一點。若是有有一摞的徹底重合的值,你能看到的,每每都是最靠上的那張紙,也就是離你眼睛最近的那一張。然而對於我們的z-index來講呢,值越大,也就至關於離你眼睛越近。在紙張裏的位置越靠上。 因此說,下面的代碼,你應該一看就能知道,哪一個元素在哪一個元素的前面。css3
.paper1 { position: absolute; background-color: orange; z-index: 2; width: 100px; height: 100px; } .paper2 { position: absolute; background-color: gray; z-index: 5; width: 50px; height: 50px; } <div class="paper1"></div> <div class="paper2"></div>
下面是結果圖,我想聰明如你,必定都猜到了。web
那麼一個問題又來了,z-index大的,必定會遮蓋住z-index小的嗎?不廢話,直接看下面的代碼。瀏覽器
.paper1 { position: absolute; width: 100px; height: 100px; background: orange; z-index: 3; } .paper2 { position: absolute; width: 200px; height: 200px; background-color: aqua; z-index: 2; } .paper3 { position: absolute; top: 80px; width: 50px; height: 50px; background-color: red; z-index: 4; } <div class="paper1"></div> <div class="paper2"> <div class="paper3"></div> </div>
你以爲哪一個的層級最高呢?來看一下最終運行的結果把。微信
居然不是.paper3在最上面,他彷佛被.paper1給擋住了,按理來講,不是z-index越大的,層級越高嗎?出現這種狀況究竟是爲何呢?flex
實際上,當z-index不爲auto的時候,會自動建立一個它本身的層級上下文,也就是說,paper1和paper2是同級的,他們都在根環境上下文上。可是paper3呢,是在paper2的環境上下文中,由於paper1的層級要比paper2要高,因此paper3的z-index哪怕再大,實際上也依然會被paper1給擋住的。網站
那麼,問題又來了,只有z-index不爲auto時纔會建立環境上下文嗎?答案確定是否認的,實際上,我們平時用到的很多css屬性,也會自動建立環境上下文,下面我們就看下mdn對這一塊所列出來的一些屬性(本文更新自2019.3.25,若是看到此文時已通過了好幾個月,甚至是一兩年,推薦看英mdn頁面:https://developer.mozilla.org...)。google
層級上下文建立條件:
flex容器的子元素,其z-index值不爲auto;
transform
filter
perspective、
clip-path
mask / mask-image / mask-border
看了上面的列表,應該會明白爲何我用z-index的時候,都會加position: absolute了吧。
那麼,若是z-index值相同時,會怎麼顯示呢?實際上,他會按照前後順序,後面的會覆蓋前面的。以下面的例子:
.paper1 { position: absolute; width: 100px; height: 100px; background: orange; z-index: 2; } .paper2 { position: absolute; width: 200px; height: 200px; background-color: aqua; z-index: 2; } <div class="paper2"></div> <div class="paper1"></div>
結果圖以下:
那麼若是此時吧兩個div調換一下位置呢?那麼就會以下圖所示這樣。
黃色的小塊已經徹底被藍色的給擋住了。不過若是是下面的代碼形式呢?
.paper1 { display: inline-block; width: 100px; height: 100px; background: orange; } .paper2 { position: absolute; width: 200px; height: 200px; background-color: aqua; top: 0; } <div class="paper1"></div> <div class="paper2"></div>
此時的話,小黃塊將會被遮擋住,不管paper1在paper2的前面和後面,最後的結果都依然是同樣的。以下圖所示
可是呢,假如給.paper1加入一個transform:scale(1)的話,他就會顯示出來,依然會按照前後順序,後面的先展現。
那麼,爲何會這樣呢?
首先呢?在一個層疊上下文中,實際上裏面不一樣的元素是有不一樣的層疊順序的,實際上下圖已經很好的說明了這一點,其從下往上依次爲
background/border->負z-index->block塊狀水平盒子->float浮動元素->inline水平盒子->z-index:auto或者是z-index: 0->正z-index。
這個和我們平時開發的表現是一致的。可是請注意z-index:auto和z-index: 0;的層級。他其實是在inline水平元素的上面,由於定位元素,以及上面所列出來的css3的標籤,不少都是默認的z-index: auto; 因此上上個例子中,絕對定位的元素,始終會覆蓋其inline-block元素。可是呢,其inline-block元素因爲新加了transform: scale(1)之後呢,實際上會默認一個z-index: auto; 因此他們倆實際上層級就一致了,所以他們也就是遵循後來居上的一個規則。誰在後面,誰就在靠上的位置。
同理,若是兩個元素分別爲z-index: 0和z-index: auto; 的話,他們倆也遵循後來居上的規則,他們倆惟一的區別,就是z-index: 0會新建一個層疊上下文,而z-index: auto;則不會;
另外,許多css3屬性中,好比說雖然transform默認是z-index: auto,可是其實際上也會新建層疊上下文,因此,這塊的話,你本身理解爲有上面列出來的css3屬性時,默認附帶了一個z-index: 0就能夠了。
固然了,我再寫一個關於負z-index的例子,做爲你們的一個小練習。不過我相信有了上面的鋪墊後,這個對於你們來講,應該就沒有很大的問題了
.paper1 { display: inline-block; width: 100px; height: 100px; background: orange; } .paper2 { position: absolute; width: 50px; height: 50px; background-color: aqua; top: 0; z-index: -1; } <div class="paper1"> <div class="paper2"></div> </div>
此時結果以下圖
此時的話呢,因爲paper2的z-index爲-1,因爲paper1和paper2都在一個層疊上下文內(root),所以呢,paper2就天然的在paper1下面。也就如上圖所示。
可是若是給.paper1增長了一個tranform: scale(1)呢,狀況就會變得不太同樣,以下圖所示:
實際上就是由於增長了transform: scale(1)之後,實際上在paper1裏面新建了一個層疊上下文,因此因爲paper2是在paper1的層疊上下文裏,因此它天然就顯示出來了。不管其z-index值有多小。
好了,上面講的也差很少了,不過依然是爲了方便你們的理解,在最後,我簡單的說一下其原理吧。
首先呢,其渲染樹是一個深度優先的樹結構,而後呢,先渲染的實際上會比後渲染的層級要更高一些,這個就跟我們用不一樣的塗料刷牆同樣,後刷的顏色老是會覆蓋先刷的那些顏色,實際上網站渲染也是相似的。同時呢,在同級的時候,後面的要比前面的層級更高,實際上也是因爲其遍歷方式決定的,這個我就很少說了。
好了,完事了,謝謝你們觀看,有什麼問題想探討的,或者我有什麼錯誤遺漏的地方,都歡迎留言給我,謝謝你們
以爲不錯的話,能夠關注微信公衆號:幹活技術,每週都有一篇前端相關原創乾貨小文章分享
推薦閱讀:
https://developers.google.com...
https://www.w3.org/TR/css-pos...
張鑫旭《CSS世界》中z-index一章