css 浮动在最上层_CSS的“层”峦“叠”翠
本文作者:高峰,360奇舞團前端工程師,W3C性能工作組/WOT工作組成員。
前言
提起,z-index大家腦海里可能會立刻浮現這樣的知識點:“z-index的值大小控制元素在Z軸上顯示的層級,z-index越大顯示的層級越高(也就是在最上層,離觀察者越近),沒有指定的按照出現順序堆疊,此外z-index不能跨父元素比較。
z-index的使用似乎就是這么簡單,對吧?
我們先看如下例1:
<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向右向上偏移。問:它們誰會顯示在上面?
demo1: https://codepen.io/verymuch/pen/jdNwOW/
如上所示,z-index為2的元素并沒有顯示在第二個元素上面。這似乎很奇怪,那到底是為什么呢?
如果你也對此存在困擾,那就和我一起往下看吧。筆者將逐步引導大家深入理解z-index的用法。
一、沒有使用z-index時元素如何堆疊?
首先,我們先了解下默認情況下,元素的堆疊,即在沒有使用z-index時,元素是如何堆疊的。
如果沒有給任何元素指定z-index,則元素按照如下順序進行堆疊(由下到上,由遠及近)。
根元素的背景和邊框
非定位的后代塊元素,按照在HTML中的出現順序進行堆疊
定位的后代塊元素,按照在HTML中的出現順序進行堆疊
注:定位的元素即為position的值不是static的元素
demo2: https://codepen.io/verymuch/pen/KJPvpQ/
如上例2所示,定位的元素(DIV#1、DIV#2、DIV#3與DIV#4)按照出現的順序堆疊。非定位的元素(DIV#5與DIV#6)雖然出現在后面,但是會被定位的元素遮蓋,不過它們本身是按照出現順序堆疊的。
注意,當使用order屬性改變flex元素子元素的出現順序時,對于堆疊規則也有同樣的影響。
如下例3所示,當將DIV#2的order改為-1后,它出現的位置為第一個,其堆疊順序也被DIV#1所遮蓋。
demo3: https://codepen.io/verymuch/pen/RvbjQX/
二、浮動塊默認如何堆疊
如果存在浮動塊,浮動塊的堆疊順序會介于無定位元素和定位元素之間。即:
根元素的背景和邊框
非定位的后代塊元素,按照在HTML中的出現順序進行堆疊
浮動塊
定位的后代塊元素,按照在HTML中的出現順序進行堆疊
我們稍微修改下示例2中的代碼,將DIV#1和DIV#3改為浮動元素。可以看到如下例4所示,浮動元素的堆疊順序高于非定位元素,低于定位元素。
demo4: https://codepen.io/verymuch/pen/pGogMq/
此外,還有一點小改動,不知道你有沒有注意到,我們將非定位元素中的文本內容改為了左對齊,但其內容并沒有被浮動元素覆蓋。這其實是浮動元素的標準效果——環繞效果。這一行為也可以列為堆疊順序之一。順序如下:
根元素的背景和邊框
非定位的后代塊元素,按照在HTML中的出現順序進行堆疊
浮動塊
非定位元素的后代行內元素
定位的后代塊元素,按照在HTML中的出現順序進行堆疊
為了讓大家清晰的理解上面所說的非定位元素的后代行內元素。大家可以看下例5。DIV#1為浮動元素,所以其層級高于在其后出現的DIV#2。此時DIV#1向右偏移,可以看見DIV#2中的行內文字元素(可以為純文字節點)層級高于DIV#1。
demo5: https://codepen.io/verymuch/pen/PVoOoX/
三、使用z-index自定義堆疊順序
以上是CSS中對于各類元素的默認排序,那我們能否自定義排序呢?答案顯然是肯定的。使用z-index可以自定義堆疊順序。
z-index的值可以為整數(正數、負數、0均可)。使用方法很簡單。
需要注意以下三點:
未指定z-index,默認為auto
如果z-index相同,則按照默認規則比較
z-index只能用于定位了的元素(暫時這么說,下文會追加解釋)。這也解釋了本文開頭的例1為什么不生效了。因為z-index對普通元素沒有效果。
如下例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對其有影響,堆疊順序與數字大小符合。
demo6: https://codepen.io/verymuch/pen/bzGYqb/
好了,相信通過上述內容,大家對于z-index應該有了一定的了解,但是以上僅僅是基本知識,關于堆疊遠遠沒有這么簡單。
想要徹底了解z-index,我們還要了解一下CSS堆疊的一個重要概念——堆疊上下文。
四、堆疊上下文
堆疊上下文是HTML中的三維概念,它抽象出了一個z軸,z軸垂直于顯示器,指向用戶(假設用戶面朝顯示區域)。
在前面的內容中,之所以有些元素的渲染順序會受到z-index影響,是因為它們都因為某種原因產生了一個堆疊上下文,而不僅僅是上文提到的定位的元素。
那么到底什么情況下會產生堆疊上下文呢?其實堆疊上下文的生成主要受到元素的屬性所影響。
如果任何一個元素滿足一下條件之一,就會生成一個堆疊上下文。
文檔的根元素(HTML)默認為一個堆疊上下文
position值為"absolute"或"relative",且z-index指定了除了auto以外值的元素
position值為"fixed"或"sticky"
彈性布局的子元素,且z-index指定了除了auto以外值的元素
opacity的值小于的元素
mix-blend-mode的值不是normal的元素
以下屬性值不為"none"的元素
transform
filter
perspective
clip-path
mask / mask-image / mask-border
isolation值為"isolate"的元素
-webkit-overflow-scrolling值為"touch"的元素
will-change指定了除初始值以外的任何屬性的元素
contain值為"layout"/"paint"及含義其中之一的組合值的元素
如上所述,有11種情況會生成堆疊上下文,對于堆疊上下文可以通過z-index指定其堆疊的順序(注意這里不是上面說的只對定位元素生效了)。
對于堆疊上下文我們需要知道以下幾點:
在每個堆疊上下文內部,子元素的堆疊規則遵循上面所講的基本規則。
堆疊上下文可以包含在其他堆疊上下文內部,它們會創建一個堆疊上下文層級結構。
堆疊上下文的層級結構與HTML的元素不同,因為對于沒有創建堆疊上下文的元素會被父元素同化。堆疊上下文的層級只包括創建了堆疊上下文的元素。
堆疊上下文獨立于其兄弟元素,在處理自身內部堆疊時,只考慮其后代元素。內部堆疊完成后,將當前堆疊上下文當成一個整體,考慮在父堆疊上下文中的堆疊順序。通俗的說,子堆疊上下文的z-index值只在父堆疊上下文中有意義。
注意,第四條和文章開頭提到的“z-index不能跨父元素比較”是不等價的,因為其限制了必須是堆疊上下文。
針對這幾點,我們看一下例7。大家可以先看一下是否理解。然后我們再講解一下。
demo7: https://codepen.io/verymuch/pen/QYbPvN/
示例7中,堆疊上下文的層級結構如下:
root
DIV#1
DIV#2
DIV#4
DIV#5
DIV#6
DIV#3
DIV#8
其中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按照上述規則進行堆疊。在其三之上。
其實有個小方法能夠幫助大家更好地判斷如何堆疊,那就是把堆疊上下文的層級結構類比為版本號。如下:
root
DIV#1 (V3)
DIV#2 (V2)
DIV#4 (V2.1)
DIV#5 (V2.3)
DIV#6 (V2.4)
DIV#3 (V1)
DIV#8 (V4)
如上,類比成版本號之后,我們就能很方便的判斷出誰上誰下啦。
五、注意事項
1.?z-index: 0與z-index: auto并不相同。
通常情況下,相鄰的兩個元素,如果其z-index值分別為0和auto,看上去沒什么區別的。如下例8所示。
DIV#1的z-index值為0,其堆疊順序并沒有高于DIV#2,而是和出現順序相同。
demo8: https://codepen.io/verymuch/pen/omKOmM/
但是實際上,這兩種情況并不相同。上面提到,當元素“position值為"absolute"或"relative",且z-index指定了除了auto以外值”時,元素會產生一個堆疊上下文,雖然元素本身堆疊順序沒有影響,但是其子元素的堆疊順序會有影響。如下例9所示。
因為DIV#1的z-index值不為auto,其產生了堆疊上下文,所以其子元素被限制在其內部,低于DIV#2(如果z-index是auto的話,DIV#3會高與DIV#2)。
demo9: https://codepen.io/verymuch/pen/yZmrWg/
2. 不要濫用z-index,將堆疊上下文的層級結構打平
筆者之所以這樣建議,是因為當堆疊上下文的層級結構比較復雜時,簡單的修改某個元素的z-index或者其他屬性,會導致一些無法預知的影響。
如下例時所示,DIV#2是DIV#1的子元素,DIV#4是DIV#3的子元素,DIV#1和DIV#3不是堆疊上下文,則DIV#2與DIV#4的堆疊順序與它們的z-index值對應。
demo10: https://codepen.io/verymuch/pen/zbOwxP/
但如果我們在某些時候需要調整DIV#3的z-index,如將其調整成z-index: 4;,那么結果就完全不一樣了。如下例11所示,DIV#4高于DIV#2了。
demo11: https://codepen.io/verymuch/pen/WmejjG/
所以筆者建議,大家一定要慎用,基于對堆疊上下文的理解基礎上,把握好頁面中堆疊上下文的層級結構,盡量保持比較淺的層級結構,最好能與HTML層級結構一致,保證自己能夠時刻知道如何進行修改與調整。
總結
以上,筆者從元素的默認堆疊順序,講到了堆疊上下文的生成。對上述內容了解之后,就能夠很好地應對開發中所遇到的層級問題了。不過還是建議大家在開發前,提前規劃好z-index的使用。避免最后自己無法掌控。
參考文獻
1.深入理解CSS中的層疊上下文和層疊順序 2.Understanding CSS z-index
關于奇舞周刊
《奇舞周刊》是360公司專業前端團隊「奇舞團」運營的前端技術社區。關注公眾號后,直接發送鏈接到后臺即可給我們投稿。
總結
以上是生活随笔為你收集整理的css 浮动在最上层_CSS的“层”峦“叠”翠的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 耳机使用说明书 jbl ua_用过JBL
- 下一篇: selenium threading运行