1. 堆疊順序
堆疊順序(stacking order):HTML 內(nèi)元素發(fā)生層疊的時(shí)候的特定垂直順序,即元素在用戶視線方向上的順序煤辨。
一般而言峦失,div 以內(nèi)在層疊順序上對于視覺有影響的一般有以下幾個(gè):
- background
- border
- 塊級元素
- 內(nèi)聯(lián)元素
- 浮動塊級元素
- 定位塊級元素
接下來一也,我們一個(gè)一個(gè)來測試一下他們的堆疊順序辰企。
1. 首先谓媒,測試一下 background 和 border 的堆疊順序。
在日常寫頁面中此再,很大可能是這樣的:
HTML
<body>
<div class="parent"></div>
</body>
CSS
.parent{
height:40px;
border:10px solid rgba(255,0,0,1);
background:#000;
}
一個(gè) div 元素內(nèi)有一個(gè) background 和一個(gè) border昔搂,它們兩者是分開的嗎?
現(xiàn)在输拇,將該 div 的 border 顏色改為半透明
.parent{
height:40px;
border:10px solid rgba(255,0,0,0.4);
background:#000;
}
從頁面效果摘符,可以很明顯地看出來,border 的顏色并不是純種的紅色策吠,而是紅色之中透著黑色议慰。
顯而易見,border 之中的黑色就是 div 元素的background奴曙。
由上面可以推斷得出别凹,border 的堆疊順序是比 background 要高的。即 border > background
2. 接下來洽糟,給 div 加一個(gè)內(nèi)聯(lián)元素和一個(gè)塊級元素
HTML
<body>
<div class="parent">
<span>內(nèi)聯(lián)元素</span>
<div class="child"></div>
</div>
</body>
CSS
.parent{
height:150px;
border:10px solid rgba(255,0,0,1);
background:#000;
}
span{
color:#fff;
}
.child{
width:80px;
height:50px;
background:green;
}
顯示效果
從上圖可以看出來炉菲,內(nèi)聯(lián)元素和塊級元素的堆疊順序都是大于 background 的堕战,那么他們與 border 相比較呢?
想辦法把這兩個(gè)元素移動到與 border 相覆蓋拍霜,就可以知道他們的堆疊順序嘱丢。
往兩個(gè)元素上分別加一個(gè) margin-left:-10px;
CSS
.parent{
height:150px;
border:10px solid rgba(255,0,0,1);
background:#000;
}
span{
color:#fff;
margin-left:-10px;
}
.child{
width:80px;
height:50px;
background:green;
margin-left:-10px;
}
顯示效果
可以知道,內(nèi)聯(lián)元素和塊級元素的堆疊順序都大于 border 的堆疊順序祠饺。那么這兩者之間的堆疊順序呢越驻?
再往塊級元素上加一個(gè) margin-top:-10px;
CSS
.parent{
height:150px;
border:10px solid rgba(255,0,0,1);
background:#000;
}
span{
color:#fff;
margin-left:-10px;
}
.child{
width:80px;
height:50px;
background:green;
margin-left:-10px;
margin-top:-10px;
}
顯示效果
從上圖可以看到,綠色背景的塊級元素向上移動 10px道偷,但是內(nèi)聯(lián)元素依然在塊級元素上面缀旁,說明內(nèi)聯(lián)元素的堆疊順序大于塊級元素的內(nèi)聯(lián)順序,即 內(nèi)聯(lián)元素 > 塊級元素 > border > background勺鸦。
3. 接下來該比較一下浮動元素了
先加一個(gè)浮動元素并巍,背景色為藍(lán)色。
HTML
<body>
<div class="parent">
<span>內(nèi)聯(lián)元素</span>
<div class="child"></div>
<div class="float"></div>
</div>
</body>
CSS
.float{
width:80px;
height:50px;
background:blue;
float:left;
}
顯示效果
現(xiàn)在换途,先測試一次懊渡,藍(lán)色的浮動元素與目前已知的最高級的內(nèi)聯(lián)元素哪個(gè)堆疊順序比較大。給浮動元素加一個(gè)margin-top:-60px;
.float{
width:80px;
height:50px;
background:blue;
float:left;
margin-top: -60px;
}
由上圖可以知道军拟,內(nèi)聯(lián)元素在浮動元素上面剃执,所以內(nèi)聯(lián)元素的堆疊順序比浮動元素大,而浮動元素又在塊級元素上面懈息,所以浮動元素的堆疊順序大于塊級元素肾档。即 內(nèi)聯(lián)元素 > 浮動元素 > 塊級元素 > border > background。
4. 接下來是定位(position:relative;和position:absolute;)元素
依然是加一個(gè)定位元素
HTML
<body>
<div class="parent">
<span>內(nèi)聯(lián)元素</span>
<div class="child"></div>
<div class="float"></div>
<div class="relative"></div>
</div>
</body>
CSS
.relative{
width:70px;
height:50px;
background:yellow;
position:relative;
}
顯示效果
依然是加margin-top:-50px;
.relative{
width:70px;
height:50px;
background:yellow;
position:relative;
margin-top:-50px;
}
可以看到漓拾,position:relative; 的元素直接蓋住了目前已知最高等級的內(nèi)聯(lián)元素,說明 position:relative; 的元素的堆疊順序比內(nèi)聯(lián)元素的要大戒祠。
接下來看一下 position:absolute; 將上面 position:relative; 改為 position:absolute;
.relative{
width:70px;
height:50px;
background:yellow;
position:absolute;
margin-top:-50px;
}
從圖片可以看出結(jié)果是一摸一樣的骇两,說明 position:relative和 position:absolute; 有一樣的堆疊順序。
所以:定位元素 > 內(nèi)聯(lián)元素 > 浮動元素 > 塊級元素 > border > background
5. 最后是 z-index 的影響
首先要知道姜盈,z-index 生效的前提是該元素是 position 屬性值是非static的元素低千,此時(shí)的 z-index為 auto。再添加一個(gè)元素馏颂,使它的 z-index生效
HTML
<body>
<div class="parent">
<span>內(nèi)聯(lián)元素</span>
<div class="child"></div>
<div class="float"></div>
<div class="relative"></div>
<div class="z-index"></div>
</div>
</body>
CSS
.z-index{
width:90px;
height:50px;
background:orange;
position:absolute;
z-index:1;
}
顯示效果
接下來示血,繼續(xù)給一個(gè)margin-top:-40px;
.z-index{
width:90px;
height:50px;
background:orange;
position:absolute;
z-index:1;
margin-top: -40px;
}
可以看到橙色的加了 z-index 的元素蓋住了定位元素,說明: 正z-index > 定位元素 > 內(nèi)聯(lián)元素 > 浮動元素 > 塊級元素 > border > background救拉。
現(xiàn)在測試一下負(fù)z-index难审,將z-index:1;改為 z-index:-1;
.z-index{
width:90px;
height:50px;
background:orange;
position:absolute;
z-index:-1;
margin-top:-40px;
}
可以看到,橙色元素完全被蓋住了亿絮。
修改一下margin告喊,試著讓它顯示出來麸拄。
.z-index{
width:90px;
height:50px;
background:orange;
position:absolute;
z-index:-1;
margin-top:0px;
}
可以看到,即使不加margin負(fù)值黔姜,依然看不到拢切。
設(shè)置margin-top:70px;
.z-index{
width:90px;
height:50px;
background:orange;
position:absolute;
z-index:-1;
margin-top:70px;
}
可以看到,橙色有一部分被背景蓋住了秆吵,說明:
正z-index > 浮動元素 > 內(nèi)聯(lián)元素 > 浮動元素 > 塊級元素 > border > background > 負(fù)z-index
綜合上面所有內(nèi)容淮椰,元素的堆疊順序就出來了。
就是下面這個(gè):
正z-index > 浮動元素 > 內(nèi)聯(lián)元素 > 浮動元素 > 塊級元素 > border > background > 負(fù)z-index
上面的順序纳寂,越大的離用戶越近主穗。
2. 堆疊上下文
堆疊上下文:stacking context,類似與作用域烈疚,由不同的CSS屬性造成的一類具有相同特征的東西黔牵,并沒有特定的概念。堆疊上下文影響的是元素 CSS 屬性中的 z-index爷肝,父元素是否是堆疊上下文猾浦,對具有z-index屬性的子元素的堆疊順序有影響。
文檔中的層疊上下文由滿足以下任意一個(gè)條件的元素形成:
- 根元素 (HTML),
- z-index 值不為 "auto"的 絕對/相對定位灯抛,
- 一個(gè) z-index 值不為 "auto"的 flex 項(xiàng)目 (flex item)金赦,即:父元素 display: flex|inline-flex的元素
- opacity 屬性值小于 1 的元素(參考 the specification for opacity),
- transform 屬性值不為 "none"的元素对嚼,
- mix-blend-mode 屬性值不為 "normal"的元素夹抗,
- filter值不為“none”的元素,
- perspective值不為“none”的元素纵竖,
- isolation 屬性被設(shè)置為 "isolate"的元素漠烧,
- position: fixed
- 在 will-change 中指定了任意 CSS 屬性,即便你沒有直接指定這些屬性的值(參考 這篇文章)
- -webkit-overflow-scrolling 屬性被設(shè)置 "touch"的元素
接下來看一下堆疊上下文對 z-index 的影響:
首先創(chuàng)建一個(gè)父元素的 div 作為容器靡砌,然后添加兩個(gè)子 div 已脓,兩個(gè)子 div 里分別添加一個(gè)子 div
HTML
<body>
<div class="parent">
<div class="a relative">
<div class="aaa">aaa</div>
</div>
<div class="b relative">
<div class="bbb">bbb</div>
</div>
</div>
</body>
接下來,使用 CSS 添加樣式通殃,此時(shí)頁面內(nèi)有一個(gè)堆疊上下文=》html 元素
CSS
.parent{
height:200px;
border:10px solid red;
background:black;
padding:10px;
}
.a,.b{
border:1px solid red;
width:200px;
height:100px;
background:green;
}
.aaa,.bbb{
background:yellow;
}
.relative{
position:relative;
}
顯示效果
接下來給 bbb 添加一個(gè) z-index:1;并使它移動到 aaa 的位置度液。
.bbb{
z-index:1;
margin-top:-90px;
}
可以看到 bbb 蓋住了 aaa ,因?yàn)?bbb 的 z-index:1; 比 aaa 默認(rèn)的 z-index:auto;更靠近用戶画舌。說明 在同一個(gè)堆疊上下文中堕担,z-index大的比z-index小的更靠近用戶
接下來使 a 和 b 形成堆疊上下文
.a,.b{
border:1px solid red;
width:200px;
height:100px;
background:green;
z-index:0;
}
頁面并沒有變化,那么這時(shí)候修改一下 aaa 和 bbb 的z-index 大小呢曲聂?將 aaa 的 z-index 改為2
.aaa{
z-index:2;
}
頁面依然沒有變化霹购,說明不同堆疊上下文中,z-index的大小不會影響到元素的堆疊順序朋腋,此時(shí)的堆疊順序與堆疊上下文所屬元素的堆疊順序有關(guān)厕鹃。
接下來讓 parent 元素形成堆疊上下文,并給 a 和 b 一個(gè)負(fù)z-index
.parent{
height:200px;
border:10px solid red;
background:black;
padding:10px;
position:relative;
z-index:0;
}
.a,.b{
border:1px solid red;
width:200px;
height:100px;
background:green;
}
.aaa,.bbb{
background:yellow;
}
.relative{
position:relative;
z-index:-1;
margin-top:50px;
}
可以看到兢仰,a 和 b 蓋住了 border,說明堆疊上下文中剂碴,負(fù)z-index > border把将。可以看作是堆疊上下文將所有元素包裹了起來,不允許有比堆疊上下文低的堆疊順序忆矛。
3. 總結(jié)
- 普通塊級元素中察蹲,z軸元素的堆疊順序如下:
正z-index > 內(nèi)聯(lián)元素 > 浮動元素 > 塊級元素 > border > background >負(fù)z-index - 堆疊上下文中,z軸元素的堆疊順序如下:
正z-index > 內(nèi)聯(lián)元素 > 浮動元素 > 塊級元素 > 負(fù)z-index > border > background - z軸順序遵循兩個(gè)原則:
- 誰大誰上
- 大小一樣催训,后來居上
部分參考自: