相信大家在工作中都遇到過這樣一些奇怪的問題:
1.為什麼我寫的z-index沒有生效?
2.為什麼z-index大的元素卻沒有蓋住z-index小的元素?
3.如何讓父元素蓋住子元素呢?
以上這些問題都跟CSS層疊上下文有關,帶著上面這些問題我們一起來了解一下什麼是CSS層疊上下文,以及這些奇怪現象背後的原理!
如果這篇文章有幫助到你,❤️關注+點贊❤️鼓勵一下作者,文章公眾號首發,關注 前端南玖
第一時間獲取最新文章~
層疊上下文是HTML元素的三維概念,這些HTML元素在一條假想的相對於面向(電腦螢幕的)視窗或者網頁的使用者的
z軸
上延伸,HTML元素依據其自身屬性按照優先順序順序佔用層疊上下文的空間。
在CSS2.1規範中,每個盒模型的位置是三維的,分別是平面畫布上的X軸
,Y軸
以及表示層疊的Z軸
。一般情況下,元素在頁面上沿X軸Y軸
平鋪,我們察覺不到它們在Z軸
上的層疊關係。而一旦元素髮生堆疊,這時就能發現某個元素可能覆蓋了另一個元素或者被另一個元素覆蓋。
我們可以這樣來理解:
瞭解了層疊上下文,我們還要知道層疊上下文是如何產生的。
一般來講有3種方法:
html中的根元素<html></html>
本身就是層疊上下文,成為根層疊上下文
position
屬性為非static
值並設定z-index
屬性為具體數值
一些CSS3屬性也能產生層疊上下文
層疊等級(stacking level,叫「層疊級別」/「層疊水平」也行),它決定了同一個層疊上下文中元素在z軸上的顯示順序(層疊順序) ,也就是說普通元素的層疊水平優先由層疊上下文決定。
「層疊順序」英文稱作」stacking order」. 表示元素髮生層疊時候有著特定的垂直顯示順序,注意,這裡跟上面兩個不一樣,上面的層疊上下文和層疊水平是概念,而這裡的層疊順序是規則。
從上面產生層疊上下文的方法,我們可以分為CSS2.1與CSS3兩類,在CSS3出來之前,相信大家都看過下面這張圖:
看到這張圖,相信大家最有疑問的是行內元素的層疊順序要高於塊級元素與浮動元素。
OK,有疑問就動手實踐一遍,看看是不是真是這樣:
<style>
div {
width: 100px;
height: 100px;
border: 1px solid saddlebrown;
}
.box1 {
position: relative;
z-index: -1;
background: violet;
}
.box2 {
margin-top: -50px;
margin-left: 50px;
background: salmon;
}
.box3 {
float: left;
margin-top: -50px;
margin-left: 100px;
background: wheat;
}
.box4 {
display: inline-block;
background: greenyellow;
margin-left: -50px;
}
.box5 {
position: relative;
z-index:0;
left: 200px;
top: -50px;
background: palevioletred;
}
.box6 {
position: relative;
z-index: 1;
left: 250px;
top: -100px;
background: gold
}
</style>
</head>
<body>
<div class="box1">1定位z-index<0</div>
<div class="box2">2塊級元素</div>
<div class="box3">3浮動</div>
<div class="box4">4行內元素</div>
<div class="box5">5定位z-index=0</div>
<div class="box6">6定位z-index>0</div>
</body>
這個理解起來其實很簡單,像border/background
屬於裝飾元素的屬性,浮動和塊級元素一般用來頁面佈局,而內聯元素一般都是文字內容,並且網頁設計之初最重要的就是文字內容,所以在發生層疊時會優先顯示文字內容,保證其不被覆蓋。
z-index
屬性設定了一個定位元素及其後代元素或 flex 專案的 z-order。當元素之間重疊的時候,z-index 較大的元素會覆蓋較小的元素在上層進行顯示。
auto
: 預設值,當前值與父級相同<integer>
: 整型數位z-index
屬性允許為負值。z-index
屬性支援 CSS3 animation
動畫。position
屬性且值不為 static
時使用。瞭解完上面這些內容,現在我們再來看一看前文提到的一些問題
這個很簡單,因為它單獨使用時不生效,一定要配合定位屬性一起,即只對指定了position屬性的元素生效——只要不是預設值static,其他的absolute、relative、fixed都可以使z-index生效。(在CSS3之後,彈性元素的子元素也可以生效)
這裡我們可以來看一個有趣的現象
<style>
.box1 {
width: 200px;
height: 100px;
background: red;
}
.box2 {
width: 100px;
height: 200px;
background: greenyellow;
}
</style>
<div style="position:relative; z-index:auto;">
<div style="position:absolute; z-index:2;" class="box1">box1--z-index=2</div>
</div>
<div style="position:relative; z-index:auto;">
<div style="position:relative; z-index:1;" class="box2">box2--z-index=1</div>
</div>
這麼看還挺正常的,z-index值大的在z-index值小的上方。接下來我們稍微改一改,你就能看到奇怪的現象了
<div style="position:relative; z-index:0;">
<div style="position:absolute; z-index:2;" class="box1">box1--z-index=2</div>
</div>
<div style="position:relative; z-index:0;">
<div style="position:relative; z-index:1;" class="box2">box2--z-index=1</div>
</div>
這裡我們只是把它們父元素的z-index
屬性從auto
改成了0
,兩種情況的表現卻截然相反。
產生這種現象的原因我們也能夠從上面的理論中找到答案:position
屬性為非 static
值並設定z-index
屬性為具體數值才能產生層疊上下文
當z-index為auto時,是一個普通元素,兩個box層比較不受父級的影響,按照規則誰大誰上,於是z-index為2的box覆蓋值為1的box; 當z-index為0時,會建立一個層疊上下文,此時的層疊規則就發生了變化。層疊上下文特性裡最後一條規則,每個層疊上下文都是獨立的。兩個box的層疊順序比較變成了優先比較其父級層疊上下文元素的層疊順序。由於兩者z-index都是0,所以,遵循層疊規則後來居上,根據在DOM出現的先後順序決定誰在上面,於是,位於後面的box2覆蓋box1。此時box元素上的z-index是沒有任何意義的。
這裡很多人是不是認為直接讓父元素的z-index
大於子元素的z-index
不就好了,可事實真是如此嗎?
<style>
.outer {
position: relative;
width: 100px;
height: 200px;
background: salmon;
z-index: 3;
}
.inner {
position: relative;
width: 50px;
height: 200px;
background: cadetblue;
z-index: 1;
}
</style>
<div class="outer">
父元素
<div class="inner">子元素</div>
</div>
有人是不是又有疑惑了?
我們這樣來理解,父元素定位+z-index為數值,所以它產生了一個層疊上下文,此時子元素無論怎麼設定z-index都不可能在父元素的下方。唯一可以實現的方法是將子元素的z-index
設為負值,而父元素只要不產生層疊上下文就可以了。
<style>
.outer {
position: relative;
width: 100px;
height: 200px;
background: salmon;
/**z-index: 3;**/
}
.inner {
position: relative;
width: 50px;
height: 200px;
background: cadetblue;
z-index: -1;
}
</style>
<div class="outer">
父元素
<div class="inner">子元素</div>
</div>
其餘規則看上面層疊順序的圖即可。
我是南玖,我們下期見!!!
-------------------------------------------
個性簽名:智者創造機會,強者把握機會,弱者坐等機會。做一個靈魂有趣的人!
如果這篇文章有幫助到你,❤️關注+點贊❤️鼓勵一下作者,文章公眾號首發,關注 前端南玖 第一時間獲取最新的文章~
歡迎加入前端技術交流群:928029210(QQ)
掃描下方二維條碼關注公眾號,回覆進群,拉你進前端學習交流群(WX),這裡有一群志同道合的前端小夥伴,交流技術、生活、內推、面經、摸魚,這裡都有哈,快來加入我們吧~ 回覆資料,獲取前端大量精選前端電子書及學習視訊~