提起,z-index 你們腦海裏可能會馬上浮現這樣的知識點:「z-index 的值大小控制元素在 Z 軸上顯示的層級,z-index 越大顯示的層級越高(也就是在最上層,離觀察者越近),沒有指定的按照出現順序堆疊,此外 z-index 不能跨父元素比較。css
z-index 的使用彷佛就是這麼簡單,對吧?前端
咱們先看以下例 1:web
<div class="box box1">DIV#1,z-index爲2</div>
<div class="box box2">DIV#2,z-index爲auto</div>
複製代碼
HTML 中有以下兩個元素,DIV#1 的 z-index 爲2
,DIV#2 向右向上偏移。問:它們誰會顯示在上面?app
點擊 CSS的「層」巒「疊」翠 - 示例1 - 用法導引 進行編輯 (@verymuch) on CodePen. 編輯器
如上所示,z-index 爲 2 的元素並無顯示在第二個元素上面。這彷佛很奇怪,那究竟是爲何呢?wordpress
若是你也對此存在困擾,那就和我一塊兒往下看吧。筆者將逐步引導你們深刻理解 z-index 的用法。佈局
首先,咱們先了解下默認狀況下,元素的堆疊,即在沒有使用 z-index 時,元素是如何堆疊的。flex
若是沒有給任何元素指定 z-index,則元素按照以下順序進行堆疊(由下到上,由遠及近)。spa
注:定位的元素即爲 position 的值不是 static 的元素code
點擊 CSS的「層」巒「疊」翠 - 示例2 - 無z-index時的默認堆疊 進行編輯 (@verymuch) on CodePen.
如上例 2 所示,定位的元素(DIV#一、DIV#二、DIV#3 與 DIV#4)按照出現的順序堆疊。非定位的元素(DIV#5 與 DIV#6)雖然出如今後面,可是會被定位的元素遮蓋,不過它們自己是按照出現順序堆疊的。
注意,當使用order
屬性改變flex
元素子元素的出現順序時,對於堆疊規則也有一樣的影響。
以下例 3 所示,當將 DIV#2 的 order 改成-1 後,它出現的位置爲第一個,其堆疊順序也被 DIV#1 所遮蓋。
點擊 CSS的「層」巒「疊」翠 - 示例3 - flex中order對出現順序的影響 進行編輯 (@verymuch) on CodePen.
若是存在浮動塊,浮動塊的堆疊順序會介於無定位元素和定位元素之間。即:
咱們稍微修改下示例 2 中的代碼,將 DIV#1 和 DIV#3 改成浮動元素。能夠看到以下例 4 所示,浮動元素的堆疊順序高於非定位元素,低於定位元素。
點擊 CSS的「層」巒「疊」翠 - 示例4 - 浮動塊的堆疊 進行編輯 (@verymuch) on CodePen.
此外,還有一點小改動,不知道你有沒有注意到,咱們將非定位元素中的文本內容改成了左對齊,但其內容並無被浮動元素覆蓋。這實際上是浮動元素的標準效果——環繞效果。這一行爲也能夠列爲堆疊順序之一。順序以下:
爲了讓你們清晰的理解上面所說的非定位元素的後代行內元素。你們能夠看下例 5。DIV#1 爲浮動元素,因此其層級高於在其後出現的 DIV#2。此時 DIV#1 向右偏移,能夠看見 DIV#2 中的行內文字元素(能夠爲純文字節點)層級高於 DIV#1。
點擊 CSS的「層」巒「疊」翠 - 示例5 - 非定位元素的後代行內元素 進行編輯 (@verymuch) on CodePen.
以上是 CSS 中對於各種元素的默認排序,那咱們可否自定義排序呢?答案顯然是確定的。使用 z-index 能夠自定義堆疊順序。
z-index 的值能夠爲整數(正數、負數、0 都可)。使用方法很簡單。
須要注意如下三點:
以下例 6,咱們修改了例 2 中元素的 z-index。
咱們會發現 DIV#5 和 DIV#6 並不受 z-index 的影響。主要體如今兩個方面,首先 DIV#5 的 z-index 大於 DIV#6,可是顯示卻低於#DIV#6;其次是 DIV#5 的 z-index 小於 DIV#4,可是仍顯示在其上面。
而對於定位的元素,z-index 對其有影響,堆疊順序與數字大小符合。
點擊 CSS的「層」巒「疊」翠 - 示例6 - 使用z-index自定義堆疊順序 進行編輯 (@verymuch) on CodePen.
好了,相信經過上述內容,你們對於 z-index 應該有了必定的瞭解,可是以上僅僅是基本知識,關於堆疊遠遠沒有這麼簡單。
想要完全瞭解 z-index,咱們還要了解一下 CSS 堆疊的一個重要概念————堆疊上下文。
堆疊上下文是 HTML 中的三維概念,它抽象出了一個 z 軸,z 軸垂直於顯示器,指向用戶(假設用戶面朝顯示區域)。
在前面的內容中,之因此有些元素的渲染順序會受到 z-index 影響,是由於它們都由於某種緣由產生了一個堆疊上下文,而不只僅是上文提到的定位的元素。
那麼到底什麼狀況下會產生堆疊上下文呢?其實堆疊上下文的生成主要受到元素的屬性所影響。
若是任何一個元素知足一下條件之一,就會生成一個堆疊上下文。
position
值爲"absolute"或"relative",且 z-index 指定了除了 auto 之外值的元素
position
值爲"fixed"或"sticky"
opacity
的值小於的元素
mix-blend-mode
的值不是
normal
的元素
isolation
值爲"isolate"的元素
-webkit-overflow-scrolling
值爲"touch"的元素
will-change
指定了除初始值之外的任何屬性的元素
contain
值爲"layout"/"paint"及含義其中之一的組合值的元素
如上所述,有 11 種狀況會生成堆疊上下文,對於堆疊上下文能夠經過 z-index 指定其堆疊的順序(注意這裏不是上面說的只對定位元素生效了)。
對於堆疊上下文咱們須要知道如下幾點:
注意,第四條和文章開頭提到的「z-index 不能跨父元素比較」是不等價的,由於其限制了必須是堆疊上下文。
針對這幾點,咱們看一下例 7。你們能夠先看一下是否理解。而後咱們再講解一下。
點擊 CSS的「層」巒「疊」翠 - 示例7 - 存在多級堆疊上下文時,元素的堆疊 進行編輯 (@verymuch) on CodePen.
示例 7 中,堆疊上下文的層級結構以下:
其中 DIV#4, DIV#5, DIV#6 是 DIV#2 的子元素,可見其堆疊順序被限制在 DIV#2 中,z-index 的值只在 DIV#2 內部有效,而後 DIV#2 又做爲一個總體與 DIV#1,DIV#3 按照上述規則進行堆疊。
DIV#7 被根元素同化,DIV#8 與 DIV#1, DIV#2, DIV#3 按照上述規則進行堆疊。在其三之上。
其實有個小方法可以幫助你們更好地判斷如何堆疊,那就是把堆疊上下文的層級結構類比爲版本號。以下:
如上,類比成版本號以後,咱們就能很方便的判斷出誰上誰下啦。
z-index: 0
與z-index: auto
並不相同。一般狀況下,相鄰的兩個元素,若是其 z-index 值分別爲0
和auto
,看上去沒什麼區別的。以下例 8 所示。
DIV#1 的 z-index 值爲 0,其堆疊順序並無高於 DIV#2,而是和出現順序相同。
點擊 CSS的「層」巒「疊」翠 - 示例8 - zindex: 0 和 auto 的區別 進行編輯 (@verymuch) on CodePen.
可是實際上,這兩種狀況並不相同。上面提到,當元素「position
值爲"absolute"或"relative",且 z-index 指定了除了 auto 之外值」時,元素會產生一個堆疊上下文,雖然元素自己堆疊順序沒有影響,可是其子元素的堆疊順序會有影響。以下例 9 所示。
由於 DIV#1 的 z-index 值不爲 auto,其產生了堆疊上下文,因此其子元素被限制在其內部,低於 DIV#2(若是 z-index 是 auto 的話,DIV#3 會高與 DIV#2)。
點擊 CSS的「層」巒「疊」翠 - 示例9 - zindex: 0 和 auto 的區別(2) 進行編輯 (@verymuch) on CodePen.
z-index
,將堆疊上下文的層級結構打平筆者之因此這樣建議,是由於當堆疊上下文的層級結構比較複雜時,簡單的修改某個元素的 z-index 或者其餘屬性,會致使一些沒法預知的影響。
以下例時所示,DIV#2 是 DIV#1 的子元素,DIV#4 是 DIV#3 的子元素,DIV#1 和 DIV#3 不是堆疊上下文,則 DIV#2 與 DIV#4 的堆疊順序與它們的 z-index 值對應。
點擊 CSS的「層」巒「疊」翠 - 示例10 - zindex形成的影響 進行編輯 (@verymuch) on CodePen.
但若是咱們在某些時候須要調整 DIV#3 的 z-index,如將其調整成z-index: 4;
,那麼結果就徹底不同了。以下例 11 所示,DIV#4 高於 DIV#2 了。
See the Pen CSS的「層」巒「疊」翠 - 示例11 - zindex形成的影響(2) by verymuch (@verymuch) on CodePen.
因此筆者建議,你們必定要慎用,基於對堆疊上下文的理解基礎上,把握好頁面中堆疊上下文的層級結構,儘可能保持比較淺的層級結構,最好能與 HTML 層級結構一致,保證本身可以時刻知道如何進行修改與調整。
以上,筆者從元素的默認堆疊順序,講到了堆疊上下文的生成。對上述內容瞭解以後,就可以很好地應對開發中所遇到的層級問題了。不過仍是建議你們在開發前,提早規劃好 z-index 的使用。避免最後本身沒法掌控。
若是你喜歡,歡迎掃碼關注個人公衆號,我會按期陪讀,並分享一些其餘的前端知識。