CSS層疊上下文、層疊等級、層疊順序、z-index

來源:互聯網
上載者:User

標籤:分享   基本   overflow   image   webkit   width   gre   它的   opacity   

以往,由於自己使用z-index的頻率不大,所以對這個CSS屬性存在比較片面的認識。一直認為z-index就是用來描述定義一個元素在螢幕Z軸上的堆疊順序。z-index值越大在Z軸

上就越靠上,也就是離螢幕觀察者越近。最後才發現這個認識存在很大的問題:

  1. 首先,z-index屬性值並不是在任何元素上都有效果。它僅在定位元素(定義了position屬性,且屬性值為非static值的元素)上有效果。
  2. 判斷元素在Z軸上的堆疊順序,不僅僅是直接比較兩個元素的z-index值的大小,這個堆疊順序實際由元素的層疊上下文層疊等級共同決定。

要想完全理解一個東西,首先要明白它是什麼,也就是它的定義。我們先看看上面提到的層疊上下文層疊等級層疊順序都是什嗎?定義又太過抽象,後面會再用一個具象的比喻來

讓你徹底明白它們到底是什麼,有什麼聯絡。

 

什麼是“層疊上下文”

層疊上下文(stacking context),是HTML中一個三維的概念。在CSS2.1規範中,每個盒模型的位置是三維的,分別是平面畫布上的X軸Y軸以及展示層疊的Z軸。一般情況下,元素在

頁面上沿X軸Y軸平鋪,我們察覺不到它們在Z軸上的層疊關係。而一旦元素髮生堆疊,這時就能發現某個元素可能覆蓋了另一個元素或者被另一個元素覆蓋。

如果一個元素含有層疊上下文,(也就是說它是層疊上下文元素),我們可以理解為這個元素在Z軸上就“高人一等”,最終表現就是它離螢幕觀察者更近。

什麼是“層疊等級”

那麼,層疊等級指的又是什嗎?層疊等級(stacking level,叫“層疊層級”/“層疊水平”也行)

  • 在同一個層疊上下文中,它描述定義的是該層疊上下文中的層疊上下文元素在Z軸上的上下順序。
  • 在其他普通元素中,它描述定義的是這些普通元素在Z軸上的上下順序。

說到這,可能很多人疑問了,不論在層疊上下文中還是在普通元素中,層疊等級都表示元素在Z軸上的上下順序,那就直接說它描述定義了所有元素在Z軸上的上下順序就OK啊!為什麼要分開描述?

為了說明原因,先舉個栗子:

具象的比喻:我們之前說到,處於層疊上下文中的元素,就像是元素當了官,等級自然比普通元素高。再想象一下,假設一個官員A是個省級領導,他下屬有一個秘書a-1,家裡有一個保姆a-2。另一個官員B是一個縣級領導,他下屬有一個秘書b-1,家裡有一個保姆b-2。a-1和b-1雖然都是秘書,但是你想一個省級領導的秘書和一個縣級領導的秘書之間有可比性嗎?甚至保姆a-2都要比秘書b-1的等級高得多。誰大誰小,誰高誰低一目瞭然,所以根本沒有比較的意義。只有在A下屬的a-1、a-2以及B下屬的b-1、b-2中相互比較大小高低才有意義。

再類比回“層疊上下文”和“層疊等級”,就得出一個結論:

  1. 普通元素的層疊等級優先由其所在的層疊上下文決定。
  2. 層疊等級的比較只有在當前層疊上下文元素中才有意義。不同層疊上下文中比較層疊等級是沒有意義的。

前面說了那麼多,知道了“層疊上下文”和“層疊等級”,其中還有一個最關鍵的問題:到底如何產生層疊上下文呢?如何讓一個元素變成層疊上下文元素呢?

其實,層疊上下文也基本上是有一些特定的CSS屬性建立的,一般有3種方法:

  1. HTML中的根項目<html></html>本身j就具有層疊上下文,稱為“根層疊上下文”。
  2. 普通元素設定position屬性為static值並設定z-index屬性為具體數值,產生層疊上下文。
  3. CSS3中的新屬性也可以產生層疊上下文。
栗子1: 有兩個div,p.a、p.b被包裹在一個div裡,p.c被包裹在另一個盒子裡,只為.a、.b、.c設定 positionz-index屬性
<style>  div {      position: relative;      width: 100px;      height: 100px;    }    p {      position: absolute;      font-size: 20px;      width: 100px;      height: 100px;    }    .a {      background-color: blue;      z-index: 1;    }    .b {      background-color: green;      z-index: 2;      top: 20px;      left: 20px;    }    .c {      background-color: red;      z-index: 3;      top: -20px;      left: 40px;    }</style><body>    <div>      <p class="a">a</p>      <p class="b">b</p>    </div>   <div>      <p class="c">c</p>    </div>  </body> 

  

 

因為p.a、p.b、p.c三個的父元素div都沒有設定 z-index,所以不會產生層疊上下文,所以.a、.b、.c都處於由 <html></html>標籤產生的“根層疊上下文”中,屬於同一個層疊上下文,此時誰的 z-index值大,誰在上面。

 

栗子2: 有兩個div,p.a、p.b被包裹在一個div裡,p.c被包裹在另一個盒子裡,同時為兩個div和.a、.b、.c設定positionz-index屬性


<style>  div {    width: 100px;    height: 100px;    position: relative;  }  .box1 {    z-index: 2;  }  .box2 {    z-index: 1;  }  p {    position: absolute;    font-size: 20px;    width: 100px;    height: 100px;  }  .a {    background-color: blue;    z-index: 100;  }  .b {    background-color: green;    top: 20px;    left: 20px;    z-index: 200;  }  .c {    background-color: red;    top: -20px;    left: 40px;    z-index: 9999;  }</style><body>  <div class="box1">    <p class="a">a</p>    <p class="b">b</p>  </div>  <div class="box2">    <p class="c">c</p>  </div></body>

  

 

我們發下,雖然 p.c元素的 z-index值為9999,遠大於 p.ap.bz-index值,但是由於 p.ap.b的父元素 div.box1產生的層疊內容相關的 z-index的值為2, p.c的父元素 div.box2所產生的層疊內容相關的 z-index值為1,所以 p.c永遠在 p.ap.b下面。

 

同時,如果我們只更改p.ap.bz-index值,由於這兩個元素都在父元素div.box1產生的層疊上下文中,所以,誰的z-index值大,誰在上面。

什麼是“層疊順序”

說完“層疊上下文”和“層疊等級”,我們再來說說“層疊順序”。“層疊順序”(stacking order)表示元素髮生層疊時按照特定的順序規則在Z軸上垂直顯示。

由此可見,前面所說的“層疊上下文”和“層疊等級”是一種概念,而這裡的“層疊順序”是一種規則。

 



在不考慮CSS3的情況下,當元素髮生層疊時,層疊順訊遵循上面途中的規則。 這裡值得注意的是:

 

  1. 左上方"層疊上下文background/border"指的是層疊上下文元素的背景和邊框。
  2. inline/inline-block元素的層疊順序要高於block(塊級)/float(浮動)元素。
  3. 單純考慮層疊順序,z-index: autoz-index: 0在同一層級,但這兩個屬性值本身是有根本區別的。
對於上面第2條,為什麼 inline/inline-block元素的層疊順序要高於 block(塊級)/ float(浮動)元素?這個大家可以思考一下! 其實很簡單,像 border/background屬於裝飾元素的屬性,浮動和區塊層級元素一般用來頁面配置,而網頁設計之初最重要的就是文字內容,所以在發生層疊時會優先顯示文字內容,保證其不被覆蓋。1、首先先看要比較的兩個元素是否處於同一個層疊上下文中:       1.1如果是,誰的層疊等級大,誰在上面(怎麼判斷層疊等級大小呢?——看“層疊順序”圖)。        1.2如果兩個元素不在統一層疊上下文中,請先比較他們所處的層疊內容相關的層疊等級。 2、當兩個元素層疊等級相同、層疊順序相同時,在DOM結構中後面的元素層疊等級在前面元素之上。 
<style>  .box1, .box2 {    position: relative;    z-index: auto;  }  .child1 {    width: 200px;    height: 100px;    background: #168bf5;    position: absolute;    top: 0;    left: 0;    z-index: 2;  }  .child2 {    width: 100px;    height: 200px;    background: #32c292;    position: absolute;    top: 0;    left: 0;    z-index: 1;  }</style></head><body>  <div class="box1">    <div class="child1"></div>  </div>  <div class="box2">    <div class="child2"></div>  </div></body>

  

 

.box1/.box2雖然設定了 position: relative,但是 z-index: auto的情況下,這兩個 div還是普通元素,並沒有產生層疊上下文。所以, child1/.child2屬於 <html></html>元素的“根層疊上下文”中,此時, 誰的z-index值大,誰在上面。對於上面代碼中的CSS代碼,我們只把 .box1/.box2z-index屬性值改為 數值0,其餘不變。 
.box1, .box2 {  position: relative;  z-index: 0;}

  

 

此時,我們發現,僅僅修改了 .box1/.box2z-index屬性值改為 數值0,最終結果完全相反。這時 .child2覆蓋在了 .child1上面。原因是什麼呢?很簡單:因為設定 z-index: 0後, .box1/.box2產生了各自的層疊上下文,這時候要比較 .child1/.child2的層疊關係完全由父元素 .box1/.box2的層疊關係決定。但是 .box1/.box2z-index值都為 0,都是區塊層級元素(所以它們的層疊等級,層疊順序是相同的),這種情況下,在 DOM結構中 後面的覆蓋前面的,所以 .child2就在上面。
CSS3中的屬性對層疊內容相關的影響

CSS3中出現了很多新屬性,其中一些屬性對層疊上下文也產生了很大的影響。如下:

  1. 父元素的display屬性值為flex|inline-flex,子項目z-index屬性值不為auto的時候,子項目為層疊上下文元素;
  2. 元素的opacity屬性值不是1
  3. 元素的transform屬性值不是none
  4. 元素mix-blend-mode屬性值不是normal`;
  5. 元素的filter屬性值不是none
  6. 元素的isolation屬性值是isolate
  7. will-change指定的屬性值為上面任意一個;
  8. 元素的-webkit-overflow-scrolling屬性值設定為touch

MagicEyes
連結:https://juejin.im/post/5b876f86518825431079ddd6
來源:掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
轉載:https://juejin.im/post/5b876f86518825431079ddd6





CSS層疊上下文、層疊等級、層疊順序、z-index

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.