層疊上下文【stacking context】
對(duì)于stacking context范咨,在MDN中的描述是
層疊上下文是HTML元素的三維概念,這些HTML元素在一條假想的相對(duì)于面向(電腦屏幕的)視窗或者網(wǎng)頁(yè)的用戶的 z 軸上延伸逻卖,HTML 元素依據(jù)其自身屬性按照優(yōu)先級(jí)順序占用層疊上下文的空間。
z軸即用戶與屏幕間看不見的垂直線昭抒。
層疊水平【stacking level】
層疊水平順序決定了同一個(gè)層疊上下文中元素在z軸上的顯示順序
層疊順序【stacking order】
不過(guò)上面圖示的說(shuō)法有一些不準(zhǔn)確灭返,按照 W3官方 的說(shuō)法,準(zhǔn)確的 7 層為:
- the background and borders of the element forming the stacking context.
- the child stacking contexts with negative stack levels (most negative first).
- the in-flow, non-inline-level, non-positioned descendants.
- the non-positioned floats.
- the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
- the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
- the child stacking contexts with positive stack levels (least positive first).
翻譯過(guò)來(lái)是:
- 形成層疊上下文環(huán)境的元素的背景與邊框
- 擁有負(fù) z-index 的子堆疊上下文元素 (負(fù)的越高越堆疊層級(jí)越低)
- 正常流式布局坤邪,非 inline-block,無(wú) position 定位(static除外)的子元素
- 無(wú) position 定位(static除外)的 float 浮動(dòng)元素
- 正常流式布局怎静, inline-block元素黔衡,無(wú) position 定位(static除外)的子元素(包括 display:table 和 display:inline )
- 擁有 z-index:0 的子堆疊上下文元素
- 擁有正 z-index: 的子堆疊上下文元素(正的越低越堆疊層級(jí)越低)
層疊準(zhǔn)則:
- 層疊上下文的水平比普通元素高。
- 當(dāng)元素的層疊水平一致夜牡、層疊順序相同的時(shí)候侣签,在DOM流中處于后面的元素會(huì)覆蓋前面的元素。
- 層疊上下文內(nèi)部嵌套的子元素均受父元素影響蹦肴。
- 層疊上下文不會(huì)影響兄弟元素猴娩,只會(huì)影響后代元素。
- 在同一層疊水平上時(shí)裂七,有明顯的z-index值仓坞,則值越大,誰(shuí)在上徙瓶。
- 使用了css3屬性的時(shí)候,層疊順序是跟z-index:auto/z-index:0是一樣的侦镇,當(dāng)他們發(fā)生層疊的時(shí)候,遵循的是“后來(lái)居上”準(zhǔn)則震捣。
注意:
- 普通元素的層疊水平優(yōu)先由層疊上下文決定,因此蒿赢,層疊水平的比較只有在當(dāng)前層疊上下文元素中才有意義渣触。
- 如果父元素沒(méi)有創(chuàng)建層疊上下文的時(shí)候羡棵,子元素沒(méi)有受父元素的限制嗅钻,父子元素是處于同一層疊水平,比較時(shí)需要按上面的7層進(jìn)行比較养篓。
- 只設(shè)置了position:absolute/relative是不會(huì)創(chuàng)建層疊上下文的,此時(shí)的div是一個(gè)普通元素觉至。
- position:fixed在chrome等較高級(jí)瀏覽器中,就算設(shè)置為z-index:auto也會(huì)創(chuàng)建層疊上下文峻贮。
層疊上下文的創(chuàng)建
以下摘自 MDN:
- 根元素 (HTML)
- z-index為數(shù)值的定位元素
- css3的屬性
- 一個(gè) z-index 值不為 "auto"的 flex 項(xiàng)目 (flex item),其子元素為層疊上下文元素
- opacity 屬性值小于 1 的元素
- transform 屬性值不為 "none"的元素
- mix-blend-mode 屬性值不為 "normal"的元素
- filter值不為“none”的元素
- perspective值不為“none”的元素
- isolation 屬性被設(shè)置為 "isolate"的元素
- position: fixed
- 在 will-change 中指定了任意 CSS 屬性纤控,即便你沒(méi)有直接指定這些屬性的值
- -webkit-overflow-scrolling 屬性被設(shè)置 "touch"的元素
demo
- 7階層疊順序
html
<div class="one">one —— z-index為負(fù)值</div>
<div class="two">two —— block塊狀水平盒子</div>
<div class="three">three —— 浮動(dòng)盒子</div>
<div class="four">four —— inline/inline-block水平盒子</div>
<div class="five">five —— z-index:auto/z-index:0</div>
<div class="six">six —— z-index為正值</div>
css
.one,.two,.three,.four,.five,.six{
width: 200px;
height: 200px;
}
.one{
position: absolute;
z-index: -1;
background: #8874c1;
}
.two{
background: #4f6fc1;
margin-left: 100px;
}
.three{
float: left;
background: #51cd8d;
margin-top: -100px;
}
.four{
display: inline-block;
background: #9cd262;
margin-left: -100px;
}
.five{
position: absolute;
background: #d9ac4c;
margin-top: -130px;
margin-left: 50px;
}
.six{
position: absolute;
z-index: 1;
background: #d93953;
margin-top: -50px;
margin-left: 150px;
}
效果圖:注意inline/inline-block的元素層級(jí)是高于float元素的碉纺,因?yàn)閕nline/inline-block是內(nèi)容展示,所以層級(jí)比較高
- 當(dāng)使用了css3屬性之后的7階層疊順序
html
<div class="one">one —— z-index為負(fù)值</div>
<div class="two">two —— block塊狀水平盒子</div>
<div class="three">three —— 浮動(dòng)盒子</div>
<div class="four">four —— inline/inline-block水平盒子</div>
<div class="five">five —— z-index:auto/z-index:0</div>
<div class="five-2">opacity</div>
<div class="five-3">transform</div>
<div class="five-4">mix-blend-mode</div>
<div class="five-5">filter</div>
<div class="five-6">isolation:isolate</div>
<div class="five-7">will-change</div>
<div class="five-1">
<div class="five-1-sub">flex子元素</div>
</div>
<div class="six">six —— z-index為正值</div>
css
.one, .two, .three,
.four, .five,.six {
width: 200px;
height: 100px;
}
.one {
position: absolute;
z-index: -1;
background: #8874c1;
}
.two {
background: #4f6fc1;
margin-left: 100px;
}
.three {
float: left;
background: #51cd8d;
margin-top: -50px;
}
.four {
display: inline-block;
background: #9cd262;
margin-left: -100px;
margin-top: -30px;
}
.five {
position: absolute;
background: #d9ac4c;
margin-top: -60px;
margin-left: 50px;
}
.six {
position: absolute;
z-index: 1;
background: #d93953;
margin-top: -100px;
margin-left: 100px;
}
.five-1,.five-2, .five-3,
.five-4,.five-5,.five-6,
.five-7 {
width: 200px;
height: 100px;
}
.five-1 {
display: flex;
margin-top: -20px;
background: pink;
}
.five-1-sub {
background: blueviolet;
z-index: 1;
}
.five-2{
opacity: 0.9;
background: red;
margin-top: -15px;
}
.five-3 {
transform: rotate(15deg);
background: #8484f1;
margin-top: -30px;
}
.five-4 {
mix-blend-mode: darken;
background: #ec57f9;
margin-top: -50px;
}
.five-5 {
filter: blur(1px);
background: #3a64d4;
margin-top: -40px;
}
.five-6 {
isolation: isolate;
background: #b18017;
margin-top: -40px;
}
.five-7 {
background: #73c1bc;
will-change: transform;
margin-top: -40px;
}
效果圖:可以明顯看出耿导,css3屬性造成的層疊上下文跟z-index:auto同一個(gè)層級(jí)态贤,并且遵循“后來(lái)居上”原則
- 當(dāng)元素的層疊水平一致、層疊順序相同的時(shí)候,在DOM流中處于后面的元素會(huì)覆蓋前面的元素箱吕。
html
<div class="one">
one
<div class="one-sub">
one-sub
</div>
</div>
<div class="two">
two
</div>
css
.one,.two,.one-sub{
width: 200px;
height: 200px;
}
.one{
position: absolute;
z-index: 5;
background: red;
}
.one-sub{
position: absolute;
z-index: 100; // 設(shè)多高都沒(méi)用
background: purple;
}
.two{
position: absolute;
left: 100px;
z-index: 5;
background: orange;
}
效果圖: 可以看到同層級(jí)的 two 是覆蓋了 one 的,而one中的子元素one-sub無(wú)論z-index層級(jí)設(shè)置多高兆旬,都是無(wú)法覆蓋 two 的
- 處于層疊上下文內(nèi)部嵌套的子元素均受父元素影響怎栽。
html
.one{
position: absolute;
background: red;
width: 400px;
height: 200px;
/* z-index: 100; */ // 不加效果為圖一,加了效果為圖二
}
.two{
position: absolute;
z-index: 2;
width: 200px;
height: 200px;
background: orange;
}
.three{
position: absolute;
z-index: -1;
width: 200px;
height: 400px;
left: 100px;
background: plum;
}
css
<div class="one">
<div class="two">two</div>
<div class="three">three</div>
</div>
效果圖:
- 圖一:one僅僅設(shè)置了position:absolute/relative; 沒(méi)有設(shè)置z-index值的時(shí)候婚瓜,z-index:默認(rèn)為auto;此時(shí)不會(huì)創(chuàng)建層疊上下文。所以此時(shí)one是普通元素巴刻,比它的子元素three的層級(jí)要高
- 圖二:當(dāng)one設(shè)置了層級(jí)之后蛉签,此時(shí)one已經(jīng)創(chuàng)建了層疊上下文,此時(shí)one里面的子元素受制one碍舍,意思就是,one的子元素層級(jí)永遠(yuǎn)比one要高片橡。
注意:chrome等較高級(jí)瀏覽器中,position:fixed;就算設(shè)置為z-index:auto也會(huì)創(chuàng)建層疊上下文捧书。所以圖一的代碼,將absolute改成fixed经瓷,也會(huì)出現(xiàn)圖二的效果。
css3屬性介紹
1. mix-blend-mode 混合模式 - 用css就能實(shí)現(xiàn)ps中的混合模式
html
<div class="img1">
<h2>變化看這里變化看這里變化看這里變化看這里</h2>
<img src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1436948145,4270509323&fm=200&gp=0.jpg">
</div>
css
.img1{
position: relative;
}
h2{
position: absolute;
left: 0;
top: 0;
mix-blend-mode: soft-light; // 有多種值可選
}
具體可看以下介紹:
mix-blend-mode MDN
CSS3混合模式mix-blend-mode/background-blend-mode簡(jiǎn)介
2. isolation — 隔離mix-blend-mode元素的混合
- isolation屬性定義該元素是否必須創(chuàng)建一個(gè)新的層疊上下文stacking context揭朝,從而阻斷混合模式色冀。
- 只要元素可以創(chuàng)建層疊上下文,就可以阻斷mix-blend-mode
具體可看以下介紹:
isolation MDN
理解CSS3 isolation: isolate的表現(xiàn)和作用
3. filter — 濾鏡效果
html
<div class="img1">
<img src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1436948145,4270509323&fm=200&gp=0.jpg">
</div>
css
.img1{
position: relative;
filter: blur(5px); // 有多種值可選
}
具體可看以下介紹:
filter MDN
- will-change
- -webkit-overflow-scrolling
PS:附贈(zèng)一道筆試題目锋恬,可以試一下是否能答對(duì)。
題目:寫出從上到下的層疊順序,例如.one .two .four ...
答案:見文末伶氢。
html
<div class="one">
<div class="two"></div>
<div class="three"></div>
</div>
<div class="four">
<div class="five"></div>
<div class="six"></div>
</div>
css
.one{
position:relative;
z-index:2;
.two{
z-index: 6;
}
.three{
position: absolute;
z-index: 5;
}
}
.four{
position:absolute;
.five{}
.six{
position: absolute;
left:0;
top:0;
z-index: -1;
}
}
本文案例可以在 css-stacking-context 中下載查看瘪吏。
參考自:
深入理解CSS中的層疊上下文和層疊順序
層疊上下文【stacking context】與層疊順序【stacking order】
層疊順序與堆棧上下文知多少
答案:three two one five four six
解析:
- one 和 four是同級(jí)元素蜗巧,由于 one是z-index數(shù)值為正的定位元素,所以one的層級(jí)比f(wàn)our高
- 既然one已經(jīng)創(chuàng)建了層疊上下文幕屹,那么它的子元素就會(huì)受限于它,接下來(lái)分析一下里面的子元素望拖。two只是設(shè)置了z-index,并沒(méi)有創(chuàng)建層疊上下文说敏,所以是普通元素,three是z-index為正值的定位元素盔沫,所以three層級(jí)比two高。目前得出的結(jié)論是three架诞、 two、 one谴忧。
- 接下來(lái)看four,因?yàn)閒our只設(shè)置了定位沾谓,沒(méi)有設(shè)置z-index,所以默認(rèn)是auto搏屑,所以four是沒(méi)有創(chuàng)建層疊上下文的,four是普通元素亮垫,也就是block塊級(jí)水平盒子的層級(jí)。
- five沒(méi)有設(shè)置任何樣式饮潦,那么他是處于block塊級(jí)水平盒子的層級(jí),基于后來(lái)居上的原則继蜡,five層級(jí)要比f(wàn)our要高,而six是z-index為負(fù)值的定位元素稀并,所以是處于z-index負(fù)值的層級(jí)仅颇,所以得出的結(jié)論就是five 碘举、four、 six引颈。
- 進(jìn)行一下排序就是three、 two蝙场、 one 、five售滤、 four 、six完箩。