前言
在編寫css樣式程式碼的時候,我們經常會遇到z-index屬性的使用,我們可能只瞭解z-index能夠提高元素的層級,並不知道具體是怎麼實現的。本文就來總結一個由z-index 引發的層疊上下文和層疊順序相關知識點,有了這方面的瞭解,才能減少開發中遇到的bug,同時這也是面試中經常遇到的問題。
正文
1、z-index 屬性
通常情況下,html 頁面被認為是二維的,相當於只有 x 和 y 軸,因為文字、影像和其他元素被排列在頁面上而不重疊。這種情況下只有一個渲染程式,所有元素都知道其他元素所佔用的空間。z-index 屬性可讓你在渲染內容時調整物件分層的順序。z-index
屬性設定了一個定位元素及其後代元素或 flex 專案的 z-order。 當元素之間重疊的時候, z-index 較大的元素會覆蓋較小的元素在上層進行顯示。這樣似的html頁面變成了一個三維的空間。
根據上面的理解,我們不難實現如下的效果:
程式碼段1如下:我們只需要改變box盒子的z-index值的大小就會改變盒子的層疊順序。
<style> div { width: 100px; height: 100px; font-size: 14px; } .box1 { position: absolute; top: 20px; left: 20px; background-color: red; } .box2 { position: absolute; top: 40px; left: 40px; background-color: yellow; } .box3 { position: absolute; top: 60px; left: 60px; background-color: green; } </style> <body> <div class="box1">box1</div> <div class="box2">box2</div> <div class="box3">box3</div> </body>
初次看上面的程式碼,會發現 z-index 值越大在z軸上就越靠上,離瀏覽器螢幕越近。但是仔細思考,你會發現這裡存在很多疑惑:z-index是在任何元素上面都有效果嗎?難道z-index的值的大小直接影響到元素的層疊順序嗎?
我們再來看下下面的程式碼段2:
<style> .box1,.box2 { width: 100px; height: 100px; font-size: 14px; display: flex; } .box1 { position: absolute; top: 20px; left: 20px; background-color: red; z-index: 1; } .box2 { position: absolute; top: 40px; left: 40px; background-color: yellow; } .box1-item1 { width: 50px; height: 100px; border: 1px solid black; } .box1-item2 { width: 50px; height: 100px; border: 1px solid blue; } .box2-item1 { width: 50px; height: 100px; border: 1px solid black; z-index: 10; } .box2-item2 { width: 50px; height: 100px; border: 1px solid blue; z-index: 10; } </style> <body> <div class="box1"> <div class="box1-item1">1</div> <div class="box1-item2">2</div> </div> <div class="box2"> <div class="box2-item1">1</div> <div class="box2-item2">2</div> </div> </body>
效果如下:
產生這樣的效果,究竟是為什麼呢,明明box2-item1、box2-item2 的z-index屬性值更大,結果這兩個盒子會被覆蓋了呢。要想徹底知道其中的緣由,我們需要知道層疊上下、層疊等級、層疊順序這幾個概念。
2、層疊上下文
層疊上下文(Stacking context),是html頁面中的一個三維的概念,就是上面提到的 z-index 的產生,導致頁面有了z軸。預設a-index值為 aotu ,即z軸的0點處,同時可以設定z-index為正值和負值,表示該層疊上下文元素在z軸距離螢幕的遠近。
3、層疊等級
層疊等級(stacking level),在同一個層疊上下文中,它描述定義的是該層疊上下文中的層疊上下文元素在Z軸
上的上下順序。在其他普通元素中,它描述定義的是這些普通元素在Z軸
上的上下順序。只有在同一層疊上下文中,層疊等級才有意義,z-index優先順序最高。產生層疊上下文的條件:
-
文件根元素(
<html>
); -
position
值為absolute
(絕對定位)或relative
(相對定位)且z-index
值不為auto
的元素; -
position
值為fixed
(固定定位)或sticky
(粘滯定位)的元素(沾滯定位適配所有移動裝置上的瀏覽器,但老的桌面瀏覽器不支援); -
flex (
flexbox
(en-US)) 容器的子元素,且z-index
值不為auto
; -
grid (
grid
) 容器的子元素,且z-index
值不為auto
; -
opacity
屬性值小於1
的元素(參見 the specification for opacity); -
mix-blend-mode
屬性值不為normal
的元素; -
以下任意屬性值不為
none
的元素:isolation
屬性值為isolate
的元素;isolation
屬性值為isolate
的元素;isolation屬性值為isolate的元素transform
filter
perspective
clip-path
mask
/mask-image
/mask-border
-
-webkit-overflow-scrolling
屬性值為touch
的元素; - isolation 屬性值為 isolate 的元素;
-
will-change
值設定了任一屬性而該屬性在 non-initial 值時會建立層疊上下文的元素(參考這篇文章); -
contain
屬性值為layout
、paint
或包含它們其中之一的合成值(比如contain: strict
、contain: content
)的元素。
在層疊上下文中,子元素同樣也按照上面解釋的規則進行層疊。 重要的是,其子級層疊上下文的 z-index
值只在父級中才有意義。子級層疊上下文被自動視為父級層疊上下文的一個獨立單元。
總結:
- 層疊上下文可以包含在其他層疊上下文中,並且一起建立一個層疊上下文的層級。
- 每個層疊上下文都完全獨立於它的兄弟元素:當處理層疊時只考慮子元素。
- 每個層疊上下文都是自包含的:當一個元素的內容發生層疊後,該元素將被作為整體在父級層疊上下文中按順序進行層疊。
4、層疊順序
層疊順序”(stacking order)表示元素髮生層疊時按照特定的順序規則在Z軸
上垂直顯示。由此可見,前面所說的“層疊上下文”和“層疊等級”是一種概念,而這裡的“層疊順序”是一種規則。
5、分析程式碼段2
程式碼段2中,因為box1 和 box2 盒子都設定了position :absolute,並且box1設定了z-index:1,使得根層級上下文中 box1層級等級高於box2,因此產生了下圖中左圖的效果。在box1 盒子中設定flex,而兩個子盒子box1-item1和box1-item2 預設的z-index值為auto,不會產生層級上下文關係,因此產生了下圖中中間的效果圖。在box2中設定了flex屬性,而裡面的 box2-item1 和 box2-item2 都設定了z-index值為10,產生了層級上下文,會高於box2 的Background 順序顯示,因此產生了下圖中有圖的效果。
寫在最後
以上就是本文的全部內容,希望給讀者帶來些許的幫助和進步,方便的話點個關注,小白的成長之路會持續更新一些工作中常見的問題和技術點。