CSS3 中的層疊上下文初探

作者:HaoyCn
文章源自:https://segmentfault.com/a/1190000003825614

前言:關(guān)于層疊上下文川尖,筆者還沒有去閱讀更詳細(xì)的 W3C 規(guī)范來了解更本質(zhì)的原理(表打我赎败,等我校招拿到 offer 了我就讀好伐 T_T)潜慎。一直聽說 CSS3 里的層疊上下文有新情況,但沒找到很好的參考資料子姜,故自己實(shí)戰(zhàn)一把洗做。鑒于筆者水平有限,如有任何遺漏或者錯(cuò)誤址芯,則懇請讀者斧正灾茁。

1 CSS2.1 中規(guī)定的層疊上下文

Background and borders — of the element forming the stacking context. The lowest level in the stack.

Negative Z-Index — the stacking contexts of descendants elements with negative z-index.

Block Level Boxes — in-flow non-inline-level non-positioned descendants.

Floated Boxes — non-positioned floats

Inline Boxes — in-flow inline-level non-positioned descendants.

Z-index: 0 — positioned elements. These form new stacking contexts.

Positive Z-index — positioned elements. The highest level in the stack.

圖文來源:What You May Not Know About the Z-Index Property

現(xiàn)在該筆者上場翻譯了窜觉!在解釋上面術(shù)語之前,需要闡明兩個(gè)術(shù)語:“定位”指的是positionrelative北专、absolute禀挫、fixed的元素,“非定位”則相反拓颓。

  • 背景和邊框:建立層疊上下文元素的背景和邊框语婴。層疊中的最低級
  • 負(fù) Z-indexz-index為負(fù)的后代元素建立的層疊上下文
  • 塊級盒:文檔流內(nèi)非行內(nèi)級非定位后代元素
  • 浮動(dòng)盒:非定位浮動(dòng)元素(筆者注:即排除了 position: relative的浮動(dòng)盒)
  • 行內(nèi)盒:文檔流內(nèi)行內(nèi)級非定位后代元素
  • Z-index: 0:定位元素。這些元素建立了新層疊上下文(筆者注:不一定驶睦,詳見后文)
  • 正 Z-index:(z-index為正的)定位元素砰左。層疊的最高等級

引文如上所表。但筆者提醒各位讀者一點(diǎn)场航,“Z-index: 0”級的定位元素不一定就會建立新的層疊上下文缠导。因?yàn)椋?/p>

CSS2.1:(z-index: auto)The stack level of the generated box in the current stacking context is 0. The box does not establish a new stacking context unless it is the root element.

當(dāng)定位元素z-index: auto,生成盒在當(dāng)前層疊上下文中的層級為0溉痢。但該盒不建立新的層疊上下文僻造,除非是根元素。

規(guī)范是這樣孩饼,但 IE6-7 有個(gè) BUG髓削,定位元素即便z-index: auto照樣創(chuàng)建層疊上下文。

以上是基于 CSS2.1 的層疊上下文介紹镀娶。下面要闡述的是在 CSS3 新環(huán)境下立膛,層疊上下文的新變化。

2 CSS3 帶來的變化

總的來說變化可以歸為兩點(diǎn)梯码,我們之后一一探討:

  1. CSS3 中許多屬性會創(chuàng)建局部層疊上下文
  2. tranform屬性改變絕對定位子元素的包含塊

2.1 產(chǎn)生新層疊上下文的情況

以下情況會產(chǎn)生新的層疊上下文:

  • 根元素(HTML)
  • 絕對或相對定位且z-index值不為auto
  • 一個(gè)伸縮項(xiàng)目Flex Item旧巾,且z-index值不為auto,即父元素display: flex|inline-flex
  • 元素的opacity屬性值小于1
  • 元素的transform屬性值不為none
  • 元素的mix-blend-mode屬性值不為normal
  • 元素的filter屬性值不為normal
  • 元素的isolation屬性值為isolate
  • position: fixed
  • will-change中指定了上述任意屬性忍些,即便你沒有直接定義這些屬性元素的-webkit-overflow-scrolling屬性值為touch

以上列表譯自:

Understanding CSS z-index—The stacking context鲁猩,提醒廣大讀者,別看中文版罢坝,因?yàn)橹形陌娌⒎菍?shí)時(shí)跟進(jìn)更新的廓握,且翻譯不太準(zhǔn)確

2.2 提升層疊上下文中的層級

以上元素建立新層疊上下文的同時(shí),也會提升元素自身所在層疊上下文中的層級嘁酿。

我們以opacity為例隙券。來看下 CSS3 規(guī)范中的話:

If an element with opacity less than 1 is not positioned, implementations must paint the layer it creates, within its parent stacking context, at the same stacking order that would be used if it were a positioned element with ‘z-index: 0’ and ‘opacity: 1’. If an element with opacity less than 1 is positioned, the ‘z-index’ property applies as described in [CSS21], except that ‘a(chǎn)uto’ is treated as ‘0’ since a new stacking context is always created.

如果元素opacity小于1且未定位,則必須在其父層疊上下文中闹司,按其在定位了的z-index: 0opacity: 1的情況中的層疊順序繪制娱仔。如果opacity小于1且已定位,z-index屬性按 CSS2.1 應(yīng)用游桩,但auto要視為0牲迫,因?yàn)樾碌膶盈B上下文總是創(chuàng)建了的耐朴。

如下案例:

div {
    width: 100px;
    height: 100px;
}
#box1 {
    position: absolute;
    background: red;
    top: 40px;
    left: 40px;
}
#box2 {
    background: blue;
}

<body>
    <div id="box1"></div>
    <div id="box2"></div>
<body>

以上 CSS 和 HTML 片段中,由于 box1 是絕對定位(層級為“Z-index: 0”級)盹憎,而 box2 是文檔流內(nèi)塊級盒(層級為“塊級盒”級)筛峭,因此 box1 會層疊在 box2 之上。下面添加如下 CSS 規(guī)則:

#box2 {
    opacity: .5;
}

這時(shí)候陪每, box2 則會層疊在 box1 之上了影晓。因?yàn)?box2 的opacity0.5(小于 1),故視其為“Z-index: 0”級檩禾,也就和 box1 同級了挂签。同級情況下,按照二者在源代碼中的順序盼产,居后的 box2 又重新占領(lǐng)高地了饵婆。

讀者可以取下面規(guī)則之任意一條實(shí)驗(yàn),都能達(dá)到同樣效果:

#box2 {
    transform: scale(1);
    mix-blend-mode: difference;
    isolation: isolate;
    -webkit-filter: blur(5px);
}

2.3 transform 改變絕對定位子元素包含塊

transform除了建立新的局部層疊上下文外辆飘,還會干一件事:改變絕對定位子元素的包含塊啦辐。須注意的是谓传,固定定位也是絕對定位的一種蜈项。

什么是包含塊?有時(shí)候一些盒子根據(jù)矩形盒計(jì)算自身定位和大小续挟,此矩形盒即包含塊紧卒。更多詳情請閱讀視覺格式化模型詳述。

固定定位元素

固定定位元素的包含塊由視口創(chuàng)建(如果讀者了解視覺格式化模型詳述的信息诗祸,也就知道這一點(diǎn):在計(jì)算其“靜態(tài)位置”的時(shí)候跑芳,則以初始化包含塊作為其計(jì)算包含塊)。現(xiàn)在我們看以下源代碼:

div {
    width: 100px;
    height: 100px;
}
#fixed {
    position: fixed;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    background: blue;
}
#transform {
    background: red;
    padding: 20px;
}

<body>
    <div id="transform">
        <div id="fixed"></div>
    </div>
</body>

這個(gè)時(shí)候直颅,以視口為包含塊進(jìn)行定位和大小計(jì)算博个, fixed將會鋪滿整個(gè)屏幕。

但現(xiàn)在功偿,我們加上如下規(guī)則:

#transform {
    transform: scale(1);
}

此時(shí)盆佣,fixed的包含塊不再是視口,而是transform的內(nèi)邊距盒的邊緣盒了械荷。故此時(shí)fixed的寬高均為140px共耍。

絕對定位元素

我們舉一個(gè)例子:

#relative {
    position: relative;
    width: 100px;
    height: 100px;
    background: green;
}
#absolute {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    background: blue;
}
#transform {
    background: red;
    width: 50px;
    height: 50px;
}

<div id="relative">
    <div id="transform">
        <div id="absolute"></div>
    </div>
</div>

此時(shí)absolute的包含塊為relative的內(nèi)邊距盒的邊緣盒。由此absolute的寬高均為100px吨瞎。然后我們添加如下規(guī)則:

#transform {
    transform: scale(1);
}

由于transform創(chuàng)建了局部層疊上下文痹兜,absolute的包含塊不再是 relative而是transform了,根據(jù)這一新的包含塊颤诀,得新寬和高為50px字旭。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末对湃,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子谐算,更是在濱河造成了極大的恐慌熟尉,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洲脂,死亡現(xiàn)場離奇詭異斤儿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)恐锦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門往果,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人一铅,你說我怎么就攤上這事陕贮。” “怎么了潘飘?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵肮之,是天一觀的道長。 經(jīng)常有香客問我卜录,道長戈擒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任艰毒,我火速辦了婚禮筐高,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘丑瞧。我一直安慰自己柑土,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布绊汹。 她就那樣靜靜地躺著稽屏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪西乖。 梳的紋絲不亂的頭發(fā)上狐榔,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機(jī)與錄音浴栽,去河邊找鬼荒叼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛典鸡,可吹牛的內(nèi)容都是我干的被廓。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼萝玷,長吁一口氣:“原來是場噩夢啊……” “哼嫁乘!你這毒婦竟也來了昆婿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤蜓斧,失蹤者是張志新(化名)和其女友劉穎仓蛆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挎春,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡看疙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了直奋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片能庆。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖脚线,靈堂內(nèi)的尸體忽然破棺而出搁胆,到底是詐尸還是另有隱情,我是刑警寧澤邮绿,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布渠旁,位于F島的核電站,受9級特大地震影響船逮,放射性物質(zhì)發(fā)生泄漏顾腊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一傻唾、第九天 我趴在偏房一處隱蔽的房頂上張望投慈。 院中可真熱鬧承耿,春花似錦冠骄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至职烧,卻和暖如春扁誓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蚀之。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工蝗敢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人足删。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓寿谴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親失受。 傳聞我的和親對象是個(gè)殘疾皇子讶泰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案咏瑟? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,728評論 1 92
  • 引自:張鑫旭的博客本文地址:http://www.zhangxinxu.com/wordpress/?p=5115...
    destiny0904閱讀 1,504評論 1 0
  • 1.z-index基礎(chǔ) z-index屬性指定了元素及其子元素的[z順序],而[z順序]可以決定當(dāng)元素發(fā)生覆蓋的時(shí)...
    徐國軍_plus閱讀 6,340評論 1 6
  • z-index 與 css 定位屬性 z-index 只對定位元素有作用痪署。 如果定位元素z-index沒有發(fā)生嵌套...
    soojade閱讀 838評論 0 2
  • 因?yàn)橐粓鰤艟陈肱ⅲ切u被遺忘又悄悄顯露的癡心雜念,繼續(xù)叨擾著生活狼犯。半夜騰起也只為一場記起余寥。人的痛苦或幸福在于,無論怎...
    青春被忘路閱讀 157評論 0 0