層疊式上下文

什麼是層疊式上下文

MDN 上對層疊式上下文的解釋爲:css

The stacking context is a three-dimensional conceptualization of HTML elements along imaginary z-axis relative to the user, who is assumed to be facing the viewport or the webpage. HTML elements occupy this space in priority order based on element attributes.html

層疊上下文(stacking context)是 HTML 元素的三維概念,這些 HTML 元素在一條假想的相對於面向(電腦屏幕的)視窗或者網頁的用戶的 z 軸上延伸,HTML 元素依據其自身屬性按照優先級順序佔用層疊上下文的空間。css3

簡單來講,正常狀況下,網頁上的內容都是一個個正常的排列,然而因爲頁面內容並無一個垂直方向的視角能夠查看,因此,當頁面上的內容發生重疊的時候,必定會有一個前後的順序來呈現,而層疊式上下文就是解決這個問題的。web

CSS 2.1 規範中,每一個盒模型的位置是三維的,通常狀況下咱們只能感知到頁面上左右方向和上下方向分別對應的 X 軸和 Y 軸,感受不到垂直於電腦屏幕的 Z 軸,以下圖所示:app

層疊順序

前面咱們講了元素髮生重疊時要有一個前後的順序來排列,那麼不一樣的元素之間就會有一個等級的比較(就是誰等級高誰在前面),那麼怎麼去斷定的等級高呢,咱們一會兒就想到了 z-index 屬性,的確,不少時候,z-index 能夠影響元素的層疊等級,可是 z-index 只能在定位的元素上起做用,而層疊等級是在每一個元素中都存在的。wordpress

每一個元素的層疊順序是由元素當前所屬的層疊式上下文和元素自己的層疊等級來決定的。也就是說比較元素的層疊順序,必須是在同一個層疊式上下文中進行比較,不然將毫無心義,具體的規則以下:flex

  1. 在同一個層疊式上下文中,層疊級別大的顯示在上面,級別小的顯示在下面。
  2. 在同一個層疊式上下文中,若是層疊級別相同,則按照它們在文檔流中的順序,寫在後面的將覆蓋前面的。
  3. 在不一樣的層疊式上下文中,元素的顯示順序依據祖先的層疊級別來決定,與自身的層疊級別無關。

在 CSS2.1(不考慮CSS3)時期,層疊順序遵循下面的圖中所示的規則:this

上面須要注意的是:spa

  1. 位於最底層的 border/background 指的是層疊上下文元素的邊框和背景色。
  2. 單純從層疊水平上看, z-index:0 和 z-index:auto 是屬於同一等級的,可是二者是有本質區別的。

如何造成層疊式上下文

前面講了層疊順序要在同一個層疊式上下文中進行比較,那麼如何造成一個層疊式上下文呢? 如下是 MDN 上總結的造成層疊式上下文的條件:3d

  1. 根元素 (HTML),造成一個根級的上下文。
  2. 定位的元素(絕對/相對定位/fixed定位),z-index 值不爲 auto 時。
  3. css3 中的一些屬性:
    • z-index 值不爲 auto 的 flex 項(父元素display:flex|inline-flex)。
    • 元素的 opacity 值不是1;
    • 元素的 transform 值 不是 none;
    • mix-blend-mode 屬性值不爲 normal 的元素;
    • filter值不爲 none 的元素;
    • perspective值不爲 none 的元素;
    • isolation 屬性被設置爲 isolate 的元素,
    • 在 will-change 中指定了任意 CSS 屬性;
    • -webkit-overflow-scrolling 屬性被設置 touch 的元素;

demo 時刻

定位與 z-index 值

<div class="box1">
  <p class="a">a盒子</p>
  <p class="b">b盒子</p>
</div>
<div class="box2">
  <p class="c">c盒子</p>
</div>
複製代碼
p {
  position: absolute;
  font-size: 20px; 
  width: 100px;
  height: 100px;
}
.a {
  background-color: aqua; 
}
.b {
  background-color: pink; 
  top: 40px;  
  left: 40px;  
}
.c {
  background-color: beige;
  top: 80px;  
  left: 80px;  
}
複製代碼

按上面代碼,此時 a、b、c 三個盒子都發生了定位,可是它們的父盒子都沒造成層疊式上下文,所以會按照文檔流的順序發生層疊,結果以下圖:

evernotecid://7F04FEFC-BAE7-46E8-9645-3E736A89ACEB/appyinxiangcom/2486197/ENResource/p1178

接下來咱們進行一下改動,給 a、b、c 三個盒子分別加上 z-index 值,

.a {
  z-index: 3;  
}
.b {
  z-index: 2;  
}
.c {
  z-index: 1;  
}

複製代碼

這時候,三個盒子自身都造成了層疊式上下文,可是它們的父盒子依舊沒有造成層疊式上下文,因此它們是同屬於一個層疊式上下文中,也就是根級,這時候它們的排列會按照各自的層疊等級進行排列,也就是 z-index 值大的在上面以下圖所示:

接下來再進行一下改進,給它們的父元素分別加上如下屬性:

div {
  position: relative;
}
.box1 {
  z-index: 1
}
.box2 {
  z-index: 2
}
複製代碼

此時呢,兩個 div 父元素都造成了一個層疊式上下文,那麼 a、b 在同一個上下文中,按照自身的層疊等級進行排列,而 它們和 c 元素則處於不一樣的層疊上下午呢中, 因此根據父級的 z-index 大小來肯定層級:

層疊順序 demo

根據前面層疊順序圖中所示,咱們建立了如下demo:

.one{
      background: #4f6fc1;
      margin-left: 100px;
}
.two{
      float: left;
      background: #51cd8d;
      margin-top: -100px;
}
.three{
     display: inline-block;
     background: #9cd262;
     margin-left: -100px;
}
複製代碼
<div class="one">one —— 塊級元素</div>
<div class="two">two —— 浮動元素</div>
<div class="three">three —— inline/inline-block 元素</div>
複製代碼

上圖能夠看出,層級關係爲:行內塊盒子(inline-block)> 浮動元素 > 塊級元素。所以若是咱們想要蓋住某一條線的話,不必定非得要用 display: relative,能夠直接用 display: inline-block 就能夠了。

接下來咱們再加入一個 z-idnex 爲負值的盒子

.four{
  position: absolute;
  z-index: -1;
  background: #8874c1;
}
複製代碼
<div class="four">four —— z-index爲負值</div>
<div class="one">one —— 塊級元素</div>
<div class="two">two —— 浮動元素</div>
<div class="three">three —— inline/inline-block 元素</div>
複製代碼

能夠看出此時,z-idnex 爲負值的盒子層級最低,跟前面的層級圖中所表示的相符合。

最後,咱們再加上 z-idnex 爲 0 和正值的盒子。

.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;
}
複製代碼
<div class="five">five —— z-index:auto/z-index:0</div>
 <div class="six">six —— z-index爲正值</div>
複製代碼

此時,5號盒子 z-index 值爲 auto,可是卻和 z-index 值爲 0 同樣的等級,可是二者本質上倒是不一樣的,前面說過,z-index 值爲 0 是建立了一個本身的層疊式上下文的,而值爲 auto 卻沒有。

最後前面介紹的幾個 CSS3 的屬性所在的層疊等級是和 z-index:auto/z-index:0 是處在同一等級的,感興趣的能夠試一下。

參考

張鑫旭-《深刻理解CSS中的層疊上下文和層疊順序》 MDN--The stacking context css層疊上下文【stacking context】和層疊順序【stacking order】

相關文章
相關標籤/搜索