說來汗顏,一直以來對於 css 常常是不求勝解。直到自己需要打造自己的輪子
才發現對z-index
完全不熟悉。
關於z-index
的問題其實非常少人完全明白它到底是怎麼運作的。事實上這並不複雜,不過如果你不曾花些時間閱讀規範可能你不曾察覺一些重要的觀念。
在下面的 html 中我們有三個元素,每乙個元素包含著乙個
,我們給
設定背景色 - 分別是綠, 紅, 藍。
每個同時也設定
absolute
位置設在檔案的左上角。約略的重疊在其他這樣我們就可以觀察整個堆疊的行為。
第乙個的
z-index: 1
,其他兩者不設。
下面是我們的程式碼:
div
span class="red" red
div span class="green" green
div span class="blue" blue
.red, .green, .blue
.red
.green
.blue
範例
這邊有個小小的挑戰: 試看看能不能把紅色區塊的排到藍色和綠色
的後面,但要遵循下面的規則。
目標要完成下面這樣,先不要偷看解答自己想一想。範例
這個解決方案是透過加入乙個小於 1
的opacity
到紅色的爸爸元素即
上面是透過加上
div:first-child
如果你現在跟我當初一樣驚訝,不相信為什麼加了opacity: .99
可以改變元素的順序。希望剩下的文章可以幫助你更清楚這些機制。
z-index
看起來非常簡單,至少在我第一次看到這個屬性的時候,我只知道越大的z-index
應該要被排在最前面(上面),對吧?
但事實上事情沒那麼單純。看起來很簡單以至於大部分的開發者都沒有花時間去理解它的規則。
在 html 中的任何元素可以被調整到其他元素的前面或後面,這也就是我們所知的堆疊順序(stacking order)。這樣順序的規則被很明確的定義在規範上,但如同我剛剛提到的,大多的開發者沒有認真的完全參透。
當我們沒有z-index
和position
屬性的時候,規則非常簡單,就是按照檔案中tag
撰寫的先後順序。好吧實際上還是有點複雜,請參考規範說明。不過呢,只要我們不使用負的 margin
來覆蓋inline
的元素,大致上我們不會遇到這些極端的情況。
當我們開始加入position
,任何被設定position
的元素和它們的後代會呈現在其他沒有設定position
的元素之前,這裡說的設定position
指的是除了設為static
以外得值例如:relative
,absolute
。
最後當我們也加入z-index
,事情就變得更複雜了一點。很自然的我們會認為具備較大z-index
的元素會排在前面,有z-index
也會蓋在沒有的前面。
但是實際上卻沒那麼簡單,首先是z-index
只對那些有設定position
的元素有效。如果你試著把z-index
設在static
的元素上,那麼什麼事都不會發生。第二點z-index
會建立乙個stacking context
,此時就是進入重點的地方了。
當我們有乙個包著一群
元素時,它們的堆疊順序通常會一起被移動(從父原則),這整個群組的順序就是
stacking context
,要完全理解stacking context
我們就必須要參透z-index
是怎麼排序stacking order
。
每乙個stacking context
有乙個唯一的 html 元素當作其根元素,當乙個新的stacking context
或者我們翻作堆疊環境
被建立在乙個
元素上時,這個堆疊環境就會控管它內部的子元素的順序stacking order
,意思是如果其中乙個元素在這個堆疊環境中順序被排在最底下,那它就完全沒機會出現在另外乙個元素排位較高的堆疊環境
前面,就算他的 z-index 設成 9999999。
從另外乙個角度來說,每乙個被設定position
的元素除了自己的stacking order
另外如果內部還有子元素,就會有乙個stacking context
來管制底下的元素。
要建立乙個堆疊環境 stacking context
有下面三者方式,只要使用其一即可:
上面提到的三種方式中,前兩者大部分的開發者都知道,即使他們不懂原理但還是會使用。第三種方式除了 w3c 規範,大多開發者都不曾提到。
此外除了opacity
另外一些新的屬性像是transforms
,filters
,css-regions
,paged media
等等都會產生 stacking context。
還有當 css 屬性需要在超出螢幕的地方渲染,他也會產生乙個 stacking context。
實際上在 global stacking 決定整個頁面元素的排序包含 borders, background, 文字是極度複雜的而且已經超出這篇文章的範圍。
不過針對大多數的應用,對於排序有些基本的認識有助於往後的開發工作,所以讓我們來一步步拆解說明
在單一的堆疊環境從最下面(後)到上面(前)規則如下
執行堆疊的根元素。
有設定position
且z-index
為負數
的元素和它們的子元素,-1 在 -2 前面
。
沒有設定position
的元素,一般元素。
有設定position
且z-index
為auto
,設定opacity
小於 1 和其他transforms
等屬性也在此列。
有設定position
且z-index
為正數
。
都一樣的時候就比檔案中程式碼出現的先後順序,後出現的蓋在上面。
注意:2 號情況在乙個 stacking context 會被排在最下面(後面),意思是他會躲在其他元素後面。也因此這讓元素藏在其父元素後面變成了可能。
你可能會疑惑上面那句話,試想如下面這樣的結構
div[z-index: 1, position: relative] /<- 這邊建立了 stacking context
div[class: 'parent']
div[z-index: -2, position: absolute] /<- 這個元素跟 parent 在同一層 stacking context 所以就躲起來了
清楚的了解乙個堆疊環境 stacking contetxt 是如何形成的以及掌握如何排序的原則後,我們不難理解乙個元素在全域的堆疊環境下會如何呈現排序,就是把
作為我們最上層的 stacking context。接著原則就一樣。
避免搞死自己的關鍵點就是每當我們建立了乙個新的堆疊環境我們要很清楚這是為了什麼。當你把z-index
設得很大但卻沒有產生變化,往上層元素看看,可能就會發現已經有人具備了stacking context
的條件了。
回到我們一開始的問題,這次我們就直接透過 html 結構來指出這些順序吧
當我們在第乙個 div 加上opacity
後,由下至上的排序應該是
本來是 6 的 span 因為上層的 div 也具備stacking context
但是順序比下面 4, 5 的 span 小。自己又因為從父原則
導致順序被往前推了。
希望這篇文章能讓你對於z-index
有能更加清楚。
CSS z index 屬性詳解
z index 屬性設定元素的堆疊順序。擁有更高堆疊順序的元素總是會處於堆疊順序較低的元素的前面。該屬性設定乙個定位元素沿 z 軸的位置,z 軸定義為垂直延伸到顯示區的軸。z index 屬性值可以是負的,如果為正數,則離使用者更近,為負數則表示離使用者更遠。z index 僅能在定位元素上奏效 p...
css z index屬性怎麼用?
css z index 屬性用於設定元素的堆疊順序 擁有更高堆疊順序的元素總是會處於堆疊順序較低的元素的前面。該屬性僅能在定位元素上奏效 例如 position absolute,position relative,or position fixed css z index屬性怎麼用?z index...
css z index屬性怎麼用
css z index 屬性用於設定元素的堆疊順序 擁有更高堆疊順序的元素總是會處於堆疊順序較低的元素的前面。該屬性僅能在定位元素上奏效 例如 position absolute,position relative,or position fixed css z index屬性怎麼用?z index...