首頁  >  文章  >  web前端  >  帶你進一步認識CSS的層疊概念

帶你進一步認識CSS的層疊概念

不言
不言轉載
2018-10-11 17:32:401838瀏覽

這篇文章帶給大家的內容是關於帶你進一步認識CSS的層疊概念,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

最近在專案的過程中遇到了一個問題,menu-bar希望始終顯示在最上面,而在之後的元素都顯示在它之下,當時設定了z-index 也沒有效果,不知道什麼原因,因此找了一下css有關層疊方面的資料,解決了這個問題,這裡記錄一下~

屏幕是一個二維平面,然而HTML元素卻是排列在三維坐標系中,x為水平位置,y為垂直位置,z為螢幕由內向外方向的位置,我們在看螢幕的時候是沿著z軸方向從外向內的;由此,元素在使用者視角就形成了層疊的關係,某個元素可能覆蓋了其他元素也可能被其他元素覆蓋;

帶你進一步認識CSS的層疊概念

那麼這裡有幾個重要的概念:層疊上下文 (堆疊上下文, Stacking Context)、層疊等級 (層疊水平, Stacking Level)、層疊順序 (層疊順序, 堆疊順序, Stacking Order)、z-index

宣告:

  1. 以下定位元素指的是position: absolute|fixed|relative|sticky

  2. #以下非定位元素指的是position: initial|static

  3. #關於層疊上下文還有一個類似的概念:區塊級格式化上下文(BFC, Block Formatting Context),可以參考一下CSS 中重要的BFC,其中也介紹了一些文件流的內容;

  4. 本文蠻長的,但如果你有勇氣看完,那應該對層疊有關概念就基本掌握了(~o ̄▽ ̄)~

1. 層疊上下文(Stacking Context)

層疊上下文(堆疊上下文, Stacking Context),是HTML中一個三維的概念。在CSS2.1規範中,每個元素的位置是三維的​​,當元素發生層疊,這時它可能覆蓋了其他元素或被其他元素覆蓋;排在z軸越靠上的位置,距離螢幕觀察者越近

文章有一個很好的比喻,這裡引用一下;

#可以想像一張桌子,上面有一堆物品,這張桌子就代表著一個層疊上下文。如果在第一張桌子旁還有第二張桌子,那第二張桌子就代表著另一個層疊上下文。

現在想像在第一張桌上有四個小方塊,他們都直接放在桌上。在這四個小方塊之上有一片玻璃,而在玻璃片上有一盤水果。這些方塊、玻璃片、水果盤,各自代表著層疊上下文中不同的層層,而這個層疊上下文就是桌子。

每一個網頁都有一個預設的層疊上下文。這個層疊上下文(桌子)的根源就是。 html標籤中的一切都被置於這個預設的層疊上下文的一個層疊層上(物品放在桌上)。

當你給了一個定位元素除auto 以外的z-index 值時,你就創建了一個新的層疊上下文,其中有著獨立於頁面上其他層疊上下文和層疊層的層疊層,這就相當於你把另一張桌子帶到了房間。

帶你進一步認識CSS的層疊概念

層疊上下文1 (Stacking Context 1)是由文檔根元素形成的, 層疊上下文2和3 (Stacking Context 2, 3) 都是層疊上下文1 (Stacking Context 1) 上的層疊層。他們各自也形成了新的層疊上下文,其中包含著新的層疊層。

在層疊上下文中,其子元素依照上面解釋的規則進行層疊。形成層疊上下文的方法有:

根元素

position值為absolute | relative,且z-index值不為auto

position 值為fixed | sticky

z-index 值不為auto 的flex元素,即:父元素display: flex | inline-flex

opacity 屬性值小於1 的元素

transform 屬性值不為none的元素

mix-blend-mode 屬性值不為normal 的元素

filter、perspective、clip-path、mask、mask-image、 mask-border、motion-path 值不為none 的元素

perspective 值不為none 的元素

isolation 屬性被設定為isolate 的元素

will-change 中指定了任意CSS 屬性,即使你沒有直接指定這些屬性的值

-webkit-overflow-scrolling 屬性被設定touch的元素

總結:

  1. #層疊上下文可以包含在其他層疊上下文中,並且一起組成了一個有層級的層疊上下文

  2. 每個層疊上下文完全獨立於它的兄弟元素,當處理層疊時只考慮子元素,這裡類似於BFC

  3. 每個層疊上下文是自包含的:當元素的內容發生層疊後,整個該元素將會在父級疊上下文中按順序進行層疊

2. 層疊等級(Stacking Level)

層疊等級 (層疊水平, Stacking Level) 決定了同一個層疊上下文中元素在z軸上的顯示順序的概念;

  • 普通元素的層疊等級優先由其所在的層疊上下文決定

  • #層疊等級的比較只有在同一個層疊上下文元素中才有意義

  • 在同一個層疊上下文中,層疊等級描述定義的是該層疊上下文中的元素在Z軸上的上下順序

注意,層疊等級不一定由z-index 決定,只有定位元素的層疊等級才由z-index 決定,其他類型元素的層疊等級由層疊順序、他們在HTML中出現的順序、他們的父級以上元素的層疊等級一同決定,詳細的規則請參考下面層疊順序的介紹。

3. z-index

在 CSS 2.1 中, 所有的盒子模型元素都處於三維座標系中。除了我們常用的橫座標和縱座標, 盒模型元素還可以沿著"z 軸"層疊擺放, 當他們相互覆蓋時, z 軸順序就變得十分重要。

-- CSS 2.1 Section 9.9.1 - Layered presentation

z-index 只適用於定位的元素,對非定位元素無效,它可以被設定為正整數、負整數、0、auto ,如果一個定位元素沒有設定z-index,那麼預設為auto;

元素的z-index 值只在同一個層疊上下文中有意義。如果父級層疊上下文的層疊等級低於另一個層疊上下文的,那麼它 z-index 設的再高也沒用。所以如果你遇到 z-index 值設了很大,但是不起作用的話,就去看看它的父級層疊上下文是否被其他層疊上下文蓋住了。

4. 層疊順序(Stacking Order)

層疊順序 (層疊序, 堆疊順序, Stacking Order) 描述的是元素在同一層疊上下文中的順序規則,從層疊的底部開始,共有七種層疊順序:

  1. #背景和邊框:形成層疊上下文的元素的背景和邊框。

  2. 負z-index值:層疊上下文內有著負z-index值的定位子元素,負的越大層疊等級越低;

  3. 區塊級盒子:文件流程中區塊層級、非定位子元素;

  4. ##浮動盒子 :非定位浮動元素;

  5. #行內盒:文檔流中行內、非定位子元素;

  6. z-index: 0:z-index為0或auto的定位元素, 這些元素形成了新的層疊上下文;

  7. 正z-index值:z-index 為正的定位元素,正的越大層疊等級越高;

#同一個層疊順序的元素按照在HTML裡出現的順序層疊;第7級順序的元素會顯示在先前順序元素的上方,也就是看起來覆蓋了更低級的元素:

帶你進一步認識CSS的層疊概念

5. 實戰

5.1 普通情況

三個relative定位的div塊中各有absolute的不同顏色的span.red、span.green、span.blue,它們都設定了position: absolute;

參見Codepen - 普通情況

那麼當沒有元素包含z-index屬性時,這個例子中的元素按照如下順序層疊(從底到頂順序):

  1. 根元素的背景和邊界

  2. 區塊級非定位元素按HTML中的出現順序層疊

  3. 行內非定位元素依HTML中的出現順序層疊

  4. #定位元素依HTML中的出現順序層疊

紅綠藍都屬於z-index為auto的定位元素,因此依照7層層疊順序規則來說同屬於層疊順序第6級,所以按HTML中的出現順序層疊:紅->綠->藍

5.2 在相同層疊上下文的父元素內的情況

紅綠位於一個p.first-box下,藍位於p.second-box下,紅綠藍都設定了position: absolute,first-box與second- box都設定了position: relative;

參見Codepen - 父元素不同但都位於根元素下

這個例子中,紅藍綠元素的父元素first-box與second-box都沒有產生新的層疊上下文,都屬於根層疊上下文中的元素,且都是層疊順序第6級,所以按HTML中的出現順序層疊:紅->綠->藍

5.3 給子元素增加z-index

紅綠位於一個p.first-box下,藍黃位於p.second-box下,紅綠藍都設定了position: absolute,如果這時給綠加上一個屬性z-index: 1,那麼此時.green位於最上面;

如果再在.second-box下.green後加上一個絕對定位的span.gold,設定z- index: -1,那麼它將位於紅綠藍的下面;

參見Codepen - 設定了z-index

這個例子中,紅藍綠黃元素的父元素中都沒有產生新的層疊上下文,都屬於根層疊上下文中的元素

  1. 紅藍都沒有設定z-index,同屬於層疊順序中的第6級,按HTML中的出現順序層疊;

  2. 綠色設定了正的z-index,屬於第7級;

  3. ##黃色設定了負的z-index,屬於第2級;

所以這個範例中的從底到高顯示的順序就是:黃->紅->藍->綠

5.4 在不同層疊上下文的父元素內的情況

紅綠位於一個p.first-box下,藍位於p.second-box下,紅綠藍都設定了position: absolute,如果first- box的z-index設定的比second-box的大,那麼此時無論藍的z-index 設定的多大z-index: 999,藍都位於紅綠的下面;如果我們只更改紅綠的z-index值,由於這兩個元素都在父元素first-box產生的層疊上下文中,此時誰的z-index值大,誰在上面;

參見Codepen - 不同層疊上下文的父元素

這個例子中,紅綠藍都屬於設定了z-index的定位元素,不過他們的父元素創造了新的層疊上下文;

1、紅綠的父元素first- box是設定了正z-index的定位元素,因此創建了一個層疊上下文,屬於層疊順序中的第7級;

2、藍的父元素second-box也同樣創建了一個層疊上下文,屬於層疊順序中的第6級;

3、依照層疊順序,first-box中所有元素都排在second-box上;

4、紅綠都屬於層疊上下文first-box中且設定了不同的正z-index,都屬於層疊順序中第7級;

#5、藍屬於層疊上下文second-box,且設定了一個很大的正z-index ,屬於層疊元素中第7級;

6、雖然藍的z-index 很大,但是因為second-box的層疊等級比first-box小,因此位於紅綠之下;

所以這個例子中從低到到顯示的順序:藍->紅->綠

#(我遇到的情況就屬於這個例子類似情形)

5.5 給子元素設定opacity

紅綠位於p.first-box下,藍色位於p.second-box下,紅綠藍都設定了position: absolute,綠色設定了z-index: 1,那麼此時綠位於紅藍的最上方;

如果此時給first-box設定opacity: .99,這時無論紅綠的z-index 設定的多大z-index: 999,藍都位於紅綠的上面;

如果再在.second-box下.green後面加上一個span.gold,設定z-index: -1,那麼它將位於紅綠藍的下面;

請參考Codepen - opacity的影響

之前已經介紹了,設定opacity也可以形成層疊上下文,因此:

1、first-box設定了opacity,first-box成為了一個新的層疊上下文;

2、second-box沒有形成新的層疊上下文,因此其中的元素都屬於根層疊上下文;

3、黃屬於層疊順序中第2級,紅綠屬於第7級,first-box屬於第6級,藍屬於層疊順序中第6級且按HTML出現順序位於first-box之上;

所以這個例子中從低到到顯示的順序:黃->紅->綠->藍

###################

以上是帶你進一步認識CSS的層疊概念的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除