CSS中層疊上下文進來了解一下?

前言

在有些 CSS 相互影響做用下,對元素設置的 z-index 並不會按實際大小疊加,一直不明白其中的原理,最近特地查了一下相關資料,作一個小總結。css

層疊上下文與層疊順序

層疊上下文(stacking content)是 HTML 中的三維概念,也就是元素z軸。層疊順序(stacking order)表示層疊時有着特定的垂直顯示順序。html

層疊準則

  • 誰大誰上

當具備明顯的層疊水平標示的時候,如識別的 z-indx 值,在同一個層疊上下文領域,層疊水平值大的那一個覆蓋小的那一個。web

  • 後來居上

當元素的層疊水平一致、層疊順序相同的時候,在DOM流中處於後面的元素會覆蓋前面的元素。瀏覽器

層疊上下文的特性

層疊上下文有如下特性:app

  • 層疊上下文的層疊水平要比普通元素高;
  • 層疊上下文能夠阻斷元素的混合模式;
  • 層疊上下文能夠嵌套,內部層疊上下文及其全部子元素均受制於外部的層疊上下文;
  • 每一個層疊上下文和兄弟元素獨立,也就是當進行層疊變化或渲染的時候,只需考慮後代元素;
  • 每一個層疊上下文是自成體系的,當元素髮生層疊的時候,整個元素被認爲是在父層疊上下文的疊層順序中;

z-index 值不是 auto 的時候,會建立層疊上下文

對於包含 position: relative; position: absolute; 的定位元素,以及 FireFox/IE瀏覽器下包含 position聲明定位的元素,當其 z-index 值不是 auto 的時候,會建立層疊上下文。flex

HTML 代碼url

<div  class="red-wrapper">

<div  class="red">小紅</div>

</div>

  

<div  class="gray-wrapper">

<div  class="gray">小灰</div>

</div>

CSS代碼spa

.red-wrapper {

position: relative;

z-index: auto;

}

  

.red {

position: absolute;

z-index: 2;

width: 300px;

height: 200px;

text-align: center;

background-color: brown;

}

  

.gray-wrapper {

position: relative;

z-index: auto;

}

  

.gray {

position: relative;

z-index: 1;

width: 200px;

height: 300px;

text-align: center;

background-color: gray;

}

z-index-auto

當兩個兄弟元素 z-index 都爲 auto 時,它們爲普通元素,子元素遵循」誰大誰上「的原則,因此小灰 z-index: 1; 輸給了小紅的 z-index: 2;,被壓在了下面code

然而當 z-index 變成數值時,就會建立一個層疊上下文,各個層疊元素相互獨立,子元素受制於父元素的層疊順序。將兄弟元素的 z-indexauto 變成了數值 0,他們的子元素的之間的層疊關係就不不受自己 z-index 的影響,而是由父級元素的 z-index 決定。orm

下面小紅和小灰的父級的 z-index 都調整成 0

.red-wrapper {

/* 其餘樣式 */

z-index: 0;

}

  

.gray-wrapper {

/* 其餘樣式 */

z-index: 0;

}

z-index-0

就會發現小灰在小紅的上面了,由於小灰的父級和小紅的父級都變成了層疊上下文元素,層疊級別同樣,根據文檔流中元素位置」後來居上「原則。

CSS3對層疊上下文的影響

display: flex|inline-flex 與層疊上下文

父級是 display: flex 或者 display: inline-flex;,子元素的 z-index 不是 auto,此時,這個子元素(注意這裏是子元素)爲層疊上下文元素。

HTML 代碼

<div  class="wrapper">

<div  class="gray">

小灰

<div  class="red">小紅</div>

</div>

</div>

CSS代碼

.wrapper {

display: flex;

}

  

.gray {

z-index: 1;

width: 200px;

height: 300px;

text-align: center;

background-color: gray;

}

  

.red {

z-index: -1;

width: 300px;

height: 200px;

text-align: center;

background-color: brown;

position: relative;

}

這樣,因爲小灰的父級的 display: flex;,自身的 z-index 不爲 auto,所以變成了層疊上下文元素,本來小紅墊底變成了小灰墊底了。

mix-blend-mode 與層疊上下文

具備 mix-blend-mode 屬性的元素是層疊上下文元素

CSS 屬性mix-blend-mode(混合模式),能夠將疊加的元素的內容和背景混合在一塊兒。

代碼同上,只需在小灰上添加 mix-blend-mode 屬性,爲了能查看到混合效果,將外面容器增長一個背景圖。

.wrapper {

background-image: url("./jz.png");

}

  

.gray {

/* 其餘樣式 */

mix-blend-mode: darken;

}

mix-blend-mode

同理,小灰有 mix-blend-mode 屬性,變成了層疊上下文元素,讓小灰墊底。

opacity 與層疊上下文

若是元素的 opacity 不爲1,這個元素爲層疊上下文元素

HTML 代碼

<div  class="gray">

小灰

<div  class="red">小紅</div>

</div>

CSS代碼

.gray {

z-index: 1;

width: 200px;

height: 300px;

text-align: center;

background-color: gray;

opacity: 0.5;

}

  

.red {

z-index: -1;

width: 300px;

height: 200px;

text-align: center;

background-color: brown;

position: relative;

}

opacity

因爲小灰自身有 opacity 半透明屬性,變成了層疊上下文元素,使得小紅 z-index: -1;也沒法穿透。

transform 與層疊上下文

應用了 transform 的元素爲層疊上下文元素

代碼同上,只不過把小灰應用 transform 變換。

.gray {

/* 其餘相關樣式 */

transform: rotate(30deg);

}

transform

同理,小灰應用 transform 變換,變成了層疊上下文元素,使得小紅 z-index: -1;也沒法穿透。

filter 與層疊上下文

具備 filter 屬性的元素是層疊上下文元素

代碼同上,只不過把小灰加上 filter 屬性。

.gray {

/* 其餘相關樣式 */

filter: blur(5px);;

}

filter

同理,小灰有 filter 屬性,變成了層疊上下文元素,使得小紅 z-index: -1; 仍是在小灰上層。

will-change 與層疊上下文

具備 will-change 屬性的元素是層疊上下文元素

代碼同上,只不過把小灰加上 will-change 屬性。

.gray {

/* 其餘相關樣式 */

filter: will-change;;

}

結果,同理如上。

總結

綜合來看元素層疊規則,首先要理解在什麼狀況下元素是層疊上下文元素

  • 含有定位屬性 position: relative|absolute|fixed;,且 z-index 不爲 autowebkit 內核瀏覽器,fixed 定位無此限制)的元素是層疊上下文元素;
  • 元素有一些 CSS3 屬性,能夠變成層疊上下文元素:
  • 父級是 display: flex|inline-flex; 子元素的 z-index 不是 auto,此時,這個子元素(注意這裏是子元素)爲層疊上下文元素
  • 具備 mix-blend-mode 屬性的元素
  • opacity 屬性不爲1的元素
  • transform 變換的元素
  • 具備 filter 屬性的元素
  • 具備 will-change 屬性的元素

其次要理解疊層準則:」誰大誰上「,」後來居上「,最後就是要了解層疊上下文主要特性(詳見文章層疊上下文的特性)。完~

相關文章
相關標籤/搜索