摘要:標簽中的一切都被置于這個默認的層疊上下文的一個層疊層上物品放在桌子上。在層疊上下文中,其子元素按照上面解釋的規則進行層疊。在中所有的盒模型元素都處于三維坐標系中。
最近在項目的過程中遇到了一個問題,menu-bar希望始終顯示在最上面,而在之后的元素都顯示在它之下,當時設置了 z-index 也沒有效果,不知道什么原因,因此找了一下css有關層疊方面的資料,解決了這個問題,這里記錄一下~
屏幕是一個二維平面,然而HTML元素卻是排列在三維坐標系中,x為水平位置,y為垂直位置,z為屏幕由內向外方向的位置,我們在看屏幕的時候是沿著z軸方向從外向內的;由此,元素在用戶視角就形成了層疊的關系,某個元素可能覆蓋了其他元素也可能被其他元素覆蓋;
那么這里有幾個重要的概念:層疊上下文 (堆疊上下文, Stacking Context)、層疊等級 (層疊水平, Stacking Level)、層疊順序 (層疊次序, 堆疊順序, Stacking Order)、z-index
聲明:
以下定位元素指的是position: absolute|fixed|relative|sticky
以下非定位元素指的是position: initial|static
關于層疊上下文還有一個類似的概念:塊級格式化上下文(BFC, Block Formatting Context),可以參考一下 CSS 中重要的BFC,其中還介紹了一些文檔流的內容;
本文蠻長的,但是如果你有勇氣看完,那應該對層疊有關概念就基本掌握了 (~o ̄▽ ̄)~
1. 層疊上下文 (Stacking Context)層疊上下文 (堆疊上下文, Stacking Context),是HTML中一個三維的概念。在CSS2.1規范中,每個元素的位置是三維的,當元素發生層疊,這時它可能覆蓋了其他元素或者被其他元素覆蓋;排在z軸越靠上的位置,距離屏幕觀察者越近
文章<關于z-index 那些你不知道的事>有一個很好的比喻,這里引用一下;
可以想象一張桌子,上面有一堆物品,這張桌子就代表著一個層疊上下文。 如果在第一張桌子旁還有第二張桌子,那第二張桌子就代表著另一個層疊上下文。
現在想象在第一張桌子上有四個小方塊,他們都直接放在桌子上。 在這四個小方塊之上有一片玻璃,而在玻璃片上有一盤水果。 這些方塊、玻璃片、水果盤,各自都代表著層疊上下文中一個不同的層疊層,而這個層疊上下文就是桌子。
每一個網頁都有一個默認的層疊上下文。 這個層疊上下文(桌子)的根源就是。 html標簽中的一切都被置于這個默認的層疊上下文的一個層疊層上(物品放在桌子上)。
當你給一個定位元素賦予了除 auto 外的 z-index 值時,你就創建了一個新的層疊上下文,其中有著獨立于頁面上其他層疊上下文和層疊層的層疊層, 這就相當于你把另一張桌子帶到了房間里。
層疊上下文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的元素
總結:
層疊上下文可以包含在其他層疊上下文中,并且一起組建了一個有層級的層疊上下文
每個層疊上下文完全獨立于它的兄弟元素,當處理層疊時只考慮子元素,這里類似于BFC
每個層疊上下文是自包含的:當元素的內容發生層疊后,整個該元素將會在父級疊上下文中按順序進行層疊
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) 描述的是元素在同一個層疊上下文中的順序規則,從層疊的底部開始,共有七種層疊順序:
背景和邊框:形成層疊上下文的元素的背景和邊框。
負z-index值:層疊上下文內有著負z-index值的定位子元素,負的越大層疊等級越低;
塊級盒:文檔流中塊級、非定位子元素;
浮動盒:非定位浮動元素;
行內盒:文檔流中行內、非定位子元素;
z-index: 0:z-index為0或auto的定位元素, 這些元素形成了新的層疊上下文;
正z-index值:z-index 為正的定位元素,正的越大層疊等級越高;
同一個層疊順序的元素按照在HTML里出現的順序層疊;第7級順序的元素會顯示在之前順序元素的上方,也就是看起來覆蓋了更低級的元素:
5. 實戰 5.1 普通情況三個relative定位的div塊中各有absolute的不同顏色的span.red、span.green、span.blue,它們都設置了position: absolute;
參見Codepen - 普通情況
那么當沒有元素包含z-index屬性時,這個例子中的元素按照如下順序層疊(從底到頂順序):
根元素的背景和邊界
塊級非定位元素按HTML中的出現順序層疊
行內非定位元素按HTML中的出現順序層疊
定位元素按HTML中的出現順序層疊
紅綠藍都屬于 z-index 為auto的定位元素,因此按照7層層疊順序規則來說同屬于層疊順序第6級,所以按HTML中的出現順序層疊:紅->綠->藍
5.2 在相同層疊上下文的父元素內的情況紅綠位于一個div.first-box下,藍位于div.second-box下,紅綠藍都設置了position: absolute,first-box與second-box都設置了position: relative;
參見Codepen - 父元素不同但都位于根元素下
這個例子中,紅藍綠元素的父元素first-box與second-box都沒有生成新的層疊上下文,都屬于根層疊上下文中的元素,且都是層疊順序第6級,所以按HTML中的出現順序層疊:紅->綠->藍
5.3 給子元素增加 z-index紅綠位于一個div.first-box下,藍黃位于div.second-box下,紅綠藍都設置了position: absolute,如果這時給綠加一個屬性z-index: 1,那么此時.green位于最上面;
如果再在.second-box下.green后加一個絕對定位的 span.gold,設置z-index: -1,那么它將位于紅綠藍的下面;
參見Codepen - 設置了z-index
這個例子中,紅藍綠黃元素的父元素中都沒有生成新的層疊上下文,都屬于根層疊上下文中的元素
紅藍都沒有設置 z-index,同屬于層疊順序中的第6級,按HTML中的出現順序層疊;
綠設置了正的 z-index,屬于第7級;
黃設置了負的 z-index,屬于第2級;
所以這個例子中的從底到高顯示的順序就是:黃->紅->藍->綠
5.4 在不同層疊上下文的父元素內的情況紅綠位于一個div.first-box下,藍位于div.second-box下,紅綠藍都設置了position: absolute,如果first-box的z-index設置的比second-box的大,那么此時無論藍的 z-index 設置的多大z-index: 999,藍都位于紅綠的下面;如果我們只更改紅綠的z-index值,由于這兩個元素都在父元素first-box產生的層疊上下文中,此時誰的z-index值大,誰在上面;
參見Codepen - 不同層疊上下文的父元素
這個例子中,紅綠藍都屬于設置了z-index的定位元素,不過他們的父元素創建了新的層疊上下文;
紅綠的父元素first-box是設置了正z-index的定位元素,因此創建了一個層疊上下文,屬于層疊順序中的第7級;
藍的父元素second-box也同樣創建了一個層疊上下文,屬于層疊順序中的第6級;
按照層疊順序,first-box中所有元素都排在second-box上;
紅綠都屬于層疊上下文first-box中且設置了不同的正 z-index,都屬于層疊順序中第7級;
藍屬于層疊上下文second-box,且設置了一個很大的正 z-index,屬于層疊元素中第7級;
雖然藍的 z-index 很大,但是因為second-box的層疊等級比first-box小,因此位于紅綠之下;
所以這個例子中從低到到顯示的順序:藍->紅->綠
(我遇到的的情況就屬于這個例子類似情形)
5.5 給子元素設置 opacity紅綠位于div.first-box下,藍位于div.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也可以形成層疊上下文,因此:
first-box設置了opacity,first-box成為了一個新的層疊上下文;
second-box沒有形成新的層疊上下文,因此其中的元素都屬于根層疊上下文;
黃屬于層疊順序中第2級,紅綠屬于第7級,first-box屬于第6級,藍屬于層疊順序中第6級且按HTML出現順序位于first-box之上;
所以這個例子中從低到到顯示的順序:黃->紅->綠->藍
網上的帖子大多深淺不一,甚至有些前后矛盾,在下的文章都是學習過程中的總結,如果發現錯誤,歡迎留言指出~
參考:
你不知道的Z-Index
MDN - z-index
What No One Told You About Z-Index
徹底搞懂CSS層疊上下文、層疊等級、層疊順序、z-index
前端性能優化之更平滑的動畫
關于z-index 那些你不知道的事
聊聊CSS中的層疊相關概念
推介閱讀:
CSS 中重要的BFC
PS:歡迎大家關注我的公眾號【前端下午茶】,一起加油吧~
另外可以加入「前端下午茶交流群」微信群,長按識別下面二維碼即可加我好友,備注加群,我拉你入群~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/116988.html
摘要:問題在寫時,有時候會遇到瀏覽器中顯示的樣式和自己的預期不符合的情況,這是因為沒有理解的層疊機制。清楚地理解了他這三大法寶,我們就能精準的預測出每個元素在瀏覽器中的樣式了。 問題: 在寫CSS時,有時候會遇到瀏覽器中顯示的樣式和自己的預期不符合的情況,這是因為沒有理解CSS的層疊機制。例如文檔中有一個p元素,用內聯樣式為他設置了顏色: 2016年10月20日 在CSS中又用不同的方式給...
摘要:元素層疊順序補充說明位于最下面的特指層疊上下文元素后面會詳解的邊框和背景色。界中可能有其他的層疊結界,而自身也可能處于其他層疊結界中。 上一篇:《CSS世界》筆記四:流的保護與破壞 寫在前面 《CSS世界》這本書還剩六章,但是這本書的精華部分主要是前面的內容,這里僅把后面章節相對重要的內容以博客展示,想著了解更多的小伙伴還是去閱讀原文的好,畢竟三百多頁的一本書并不是小小幾篇博客能完全說...
摘要:知道存在是很有用的,這樣當你在別人的代碼中遇到它時,你就知道它是什么了。如上面所示的示例所示,元素選擇器具有很低的特殊性。類選擇器具有更高特殊性,所以將戰勝元素選擇器。個位在整個選擇器中每包含一個元素選擇器或偽元素就在該列中加分。 在實際的工作中,我們可能還有些疑惑,當有多個選擇器作用在一個元素上時,哪個規則最終會應用到元素上?其實這是通過層疊機制來控制的,這也和樣式繼承(元素從其父元...
摘要:栗子有兩個,被包裹在一個里,被包裹在另一個盒子里,同時為兩個和設置和屬性效果我們發下,雖然元素的值為,遠大于和的值,但是由于的父元素產生的層疊上下文的的值為,的父元素所產生的層疊上下文的值為,所以永遠在和下面。 前言 最近,在項目中遇到一個關于CSS中元素z-index屬性的問題,具體問題不太好描述,總結起來就是當給元素和父元素色設置position屬性和z-index相關屬性后,頁面...
摘要:栗子有兩個,被包裹在一個里,被包裹在另一個盒子里,同時為兩個和設置和屬性效果我們發下,雖然元素的值為,遠大于和的值,但是由于的父元素產生的層疊上下文的的值為,的父元素所產生的層疊上下文的值為,所以永遠在和下面。 前言 最近,在項目中遇到一個關于CSS中元素z-index屬性的問題,具體問題不太好描述,總結起來就是當給元素和父元素色設置position屬性和z-index相關屬性后,頁面...
閱讀 1829·2023-04-26 00:59
閱讀 3129·2021-11-15 18:10
閱讀 3072·2021-09-22 16:02
閱讀 766·2021-09-02 15:15
閱讀 3716·2019-08-30 15:56
閱讀 1917·2019-08-30 15:54
閱讀 2858·2019-08-29 16:31
閱讀 2035·2019-08-29 16:10