淺談為什么我的 z-index 又不生效了

表面看起來,z-index
似乎是一個(gè)很簡(jiǎn)單的屬性,你給它設(shè)置哪個(gè)值,元素就會(huì)位于 z
軸的哪個(gè)位置。但它實(shí)際上并沒有我們想象的這么簡(jiǎn)單,這個(gè)屬性背后是一系列決定元素所在層級(jí)的規(guī)則。
在進(jìn)行今天的介紹前,我們先列出三個(gè)問題,如果你能一眼看出它們的解決方案,那么恭喜你掌握了z-index
,也就不需要閱讀本文了;如果不行,那么耐心看完本文,相信能找到答案。
三個(gè)自測(cè)問題
- 問題一:為什么
z-index
數(shù)值更大,但Content
沒有在Box 2
之上?
<div id="box1"> Box 1 </div> <div id="content"> Content <br/> z-index: 2; </div> <div id="box2"> Box 2 <br/> z-index: 1; </div>
div { padding: 25px; font-size: larger; } #box1 { background-color: chocolate; width: 200px; height: 100px; margin-bottom: -50px; } #content { background-color: gold; width: 300px; height: 200px; z-index: 2; } #box2 { background-color: cyan; width: 200px; height: 100px; margin-top: -50px; z-index: 1; }
- 問題二:明明
z-index
數(shù)值更小,為什么Content
這次反而在Box 2
之上了?
<div id="box1"> Box 1 </div> <div id="content"> Content <br/> transform: rotate(90deg); <br/> z-index: 1; </div> <div id="box2"> <br/> Box 2 <br/> z-index: 2; </div>
div { padding: 25px; font-size: larger; } #box1 { background-color: chocolate; width: 200px; height: 100px; margin-bottom: -10px; } #content { background-color: gold; width: 250px; height: 200px; z-index: 1; transform: rotate(90deg); } #box2 { background-color: cyan; width: 200px; height: 100px; margin-top: -10px; z-index: 2; }
- 問題三:為什么明明
z-index
是最大的,但Box 2-3
在Content
之下?
<div id="box1"> Box 1 </div> <div id="content"> Content <br/> z-index: 2; <br/> position: relative; </div> <div id="box2"> <br/><br/> Box 2 <br/> z-index: 1; <br/> position: relative; <div id="box2-3"> Box 2-3 <br/> z-index: 5; <br/> position: absolute; </div> </div>
div { padding: 25px; font-size: larger; } #box1 { background-color: chocolate; width: 200px; height: 100px; margin-bottom: -50px; } #content { background-color: gold; width: 200px; height: 100px; margin-left: 50px; z-index: 2; position: relative; } #box2 { background-color: cyan; width: 200px; height: 100px; margin-top: -50px; z-index: 1; position: relative; } #box2-3 { background-color: green; width: 200px; height: 100px; padding-left: 150px; left: 180px; top: -50px; z-index: 5; position: absolute; }
z-index 簡(jiǎn)介
沒有使用 z-index
的時(shí)候,元素的層疊關(guān)系由2個(gè)因素決定:
- 該元素的
position
是否是static
,如果是static
,那么這個(gè)元素就稱為non-positioned
;反之,如果position
值是relative
,absolute
,fixed
, 或sticky
則稱positioned
。positioned
元素享受特權(quán),會(huì)覆蓋non-positioned
元素。而non-positioned
元素中,有float
樣式的元素覆蓋沒有float
的。 - 元素的“出場(chǎng)”順序 —— 即在html中的順序,同類型元素遵循后來者居上的原則。
z-index
屬性設(shè)定了一個(gè)定位元素及其后代元素或 flex
項(xiàng)目的 z-order
。當(dāng)元素之間重疊的時(shí)候,z-index
較大的元素會(huì)覆蓋較小的元素在上層進(jìn)行顯示。
所謂 z-index
,只有在以下場(chǎng)景適用。分別為:
- 首先,
z-index
這個(gè)屬性并不是在所有的元素上都有效果。它僅僅只在positioned
元素上有效果。 - 要判斷元素在
z軸
上的堆疊順序,并不僅僅是直接比較兩個(gè)元素的 z-index 值的大小,同時(shí),這個(gè)堆疊順序還由元素的層疊上下文和層疊等級(jí)共同決定。
層疊上下文
z-index
存在的一個(gè)背景是 Stacking Context
,中文常譯作層疊上下文(其實(shí)數(shù)據(jù)結(jié)構(gòu)中的棧的單詞也是 stack,所以層疊上下文中已經(jīng)蘊(yùn)含了后來者居上的意思)。
層疊上下文,是HTML中一個(gè)三維的概念。在 CSS2.1
規(guī)范中,每個(gè)盒模型的位置是三維的,分別是平面畫布上的X軸
,Y軸
以及表示層疊的Z軸
。
一般情況下,元素在頁面上沿 X軸
和 Y軸
平鋪,我們是察覺不到它們?cè)?code>Z軸上的層疊關(guān)系。而一旦元素發(fā)生堆疊,這時(shí)就能發(fā)現(xiàn)某個(gè)元素可能覆蓋了另一個(gè)元素或者被另一個(gè)元素覆蓋。
如果一個(gè)元素含有層疊上下文,(也就是說它是層疊上下文元素),我們可以理解為這個(gè)元素在Z軸上就“高人一等”,最終表現(xiàn)就是它離屏幕觀察者更近。
構(gòu)建層疊上下文和蓋樓比較類似:
首先, <html>
元素是地平線或地基 —— 所有樓都是從地基開始蓋的
接下來,每產(chǎn)生一個(gè)層疊上下文,相當(dāng)于蓋一座樓, z-index 的值相當(dāng)于樓的高度
以下幾種元素可以產(chǎn)生層疊上下文:
- 元素的
position
值為absolute
或relative
, 且z-index
值不為auto
(默認(rèn)值). - 元素的
position
值為fixed
或sticky
- 元素是
flexbox
容器的子元素, 且z-index
值不為auto
(默認(rèn)值) - 元素是
grid
容器的子元素, 且z-index
值不為auto
(默認(rèn)值) - 元素有
opacity
值且值小于 1. - 元素有以下任意一項(xiàng)的值,且值不為
none
:transform
filter
perspective
clip-path
mask / mask-image / mask-border
- 元素有
isolation
值且值為isolate
. - 元素有
mix-blend-mode
值且值不為normal
. - 元素有
-webkit-overflow-scrolling
值且值為touch
. - 其他幾種冷門的情況
第三,層疊上下文是可以嵌套的 —— 這是最容易讓人誤解的一塊。
嵌套,顧名思義就是在一個(gè) 層疊上下文
中能創(chuàng)建 另一個(gè)層疊上下文
。
假如在地基上蓋一座50米高的樓(即 z-index: 50
), 是否可以在樓里再蓋一棟 100米高的樓中樓呢?
當(dāng)然不可能!但是你可以在這座樓里建一座 100
級(jí)階梯高的大堂。
換句話說,在嵌套的層疊上下文中,子層疊上下文被限制在了父層疊上下文中,它們的 z-index
“單位”已經(jīng)不一樣了(z-index
沒有單位,這邊只是用于理解),無論子層疊上下文的 z-index
值有多大都無法突破父層疊上下文的高度。
層疊上下文小結(jié):
- 元素的第一級(jí)層疊上下文
- 特定樣式的元素可以產(chǎn)生新的層疊上下文,且z-index的值在這些元素中才有效
- 子層疊上下文的“高度”被限制在了父層疊上下文中
- 在同級(jí)層疊上下文中,沒有(有效) z-index 的元素依然遵循上一小節(jié)的規(guī)律;z-index 值相同的元素遵循后來者居上原則。
需要注意:層疊上下文嵌套
與 元素嵌套
不是一一對(duì)應(yīng)的關(guān)系,一個(gè)元素所處的父層疊上下文是由內(nèi)向外找到的第一個(gè)能產(chǎn)生層疊上下文的元素所產(chǎn)生的層疊上下文。
看個(gè)例子便于理解:
<div id="div1" style="position: relative; z-index: 1"> <div id="div2" style="position: relative; z-index: 1"> 所處的父層疊上下文是 div1 產(chǎn)生的層疊上下文 </div> <div id="div3"> <div id="div4" style="position: relative; z-index: 2"> 所處的父層疊上下文也是 div1 產(chǎn)生的層疊上下文 </div> </div> </div>
雖然 div4
外面還有層 div3
,但是由于 div3
不能產(chǎn)生層疊上下文,所以 div4
所處的父層疊上下文也是 div1
(產(chǎn)生的層疊上下文) —— 雖然在html
元素層級(jí)中 div4
比 div2
更深了一級(jí),但是 div4
與 div2
在層疊上下文層面上是同級(jí)的,因此它們可以相互比較 z-index
值來決定誰在上面。
三個(gè)問題的解答
學(xué)習(xí)完上面的 z-index
相關(guān)知識(shí)點(diǎn),我們來回答開頭提出的三個(gè)問題。
-
第一個(gè)問題中
z-index
不生效的原因在于這三個(gè)元素都不能產(chǎn)生層疊上下文,因此z-index
值對(duì)它們不生效 —— 根據(jù)出場(chǎng)順序決定了Content
處在Box 2
之下。 -
第二個(gè)問題的
Box 2
不能產(chǎn)生層疊上下文,因此z-index
同樣是無效的;Content
因?yàn)槭褂昧?transform
屬性,產(chǎn)生了層疊上下文,相當(dāng)于蓋了一座 1 米高的樓(z-index: 1
) -
Box 2
與Content
在同一級(jí)層疊上下文中,且Box 2
的z-index
比較小, 因此Box 2
在Content
之下;且Box 2-3
在Box 2
的層疊上下文下新建了個(gè)子層疊上下文,因此Box 2-3
的高度被限制在了Box 2
之內(nèi),因此Box 2-3
的z-index
再高也沒用。
到此這篇關(guān)于淺談為什么我的 z-index 又不生效了的文章就介紹到這了,更多相關(guān)z-index不生效內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!
相關(guān)文章
- 設(shè)置z-index時(shí)必須要固定位置,這樣設(shè)置它的值時(shí)才能奏效(例如 position:absolute;)下面是示例代碼,在ff3.5.5和ie5.5~ie8.0RC1中通過,大家可以嘗試著不固定其位置試試2009-11-26