css元素層疊順序詳解

admin發表於2018-05-24
在css中,每一個盒模型的位置都是三維的,x軸和y軸定位,還有盒與盒之間的層疊關係。

定位元素,可以通過z-index屬性來確定它們之間的相互層疊關係,具體可以參閱CSS z-index屬性一章節,但這只是盒模型層疊規則的一部分,下面就深入介紹一下這方面的相關知識。

先來看一段程式碼例項:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style type="text/css">
.container{
  position:relative;
  background:#ccc;
}
.container > div{
  width:200px;
  height:200px;
}
.float{
  float:left;
  background-color:blue;
}
.inline-block{
  display:inline-block;
  background-color:green;
  margin-left:-100px;
}
</style>
</head>
<body>
<div class="container">
  <div class="inline-block">螞蟻部落一</div>
  <div class="float">螞蟻部落二</div>
</div>
</body>
</html>

從上面的程式碼表現可以看出,是內聯塊級元素覆蓋在了float元素之上;兩個元素交換位置也是如下:

[HTML] 純文字檢視 複製程式碼
<div class="container">
  <div class="float">螞蟻部落二</div>
  <div class="inline-block">螞蟻部落一</div>
</div>

雖然上面的元素都不是定位元素,但是還是有層疊關係,這涉及到stacking level(層疊級別)知識。

下面這個圖片就能夠介紹上面的現象:

a:3:{s:3:\"pic\";s:43:\"portal/201702/05/132257ri1tw184gtv3vu8t.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

上面的圖片表示不同型別盒層疊級別的高低,下面由低到高進行一下說明:

(1).背景和邊框:建立當前層疊上下文元素的背景和邊框。

(2).負的z-index:當前層疊上下文中,z-index屬性值為負的元素。

(3).塊級盒:文件流內非行內級非定位後代元素。

(4).浮動盒:非定位浮動元素。

(5).行內盒:文件流內行內級非定位後代元素。

(6).z-index:0:層疊級數為0的定位元素。

(7).正z-index:z-index屬性值為正的定位元素。

特別說明:當定位元素z-index:auto,生成盒在當前層疊上下文中的層級為 0,不會建立新的層疊上下文,除非是根元素。

建立層疊上下文:

只要滿足一定的條件,元素就可以建立一個層疊上下文,下面就簡單進行一下羅列:

(1).HTML根元素會天然建立一個層疊上下文,無需特殊條件。

(2).絕對定位元素或者相對定位元素,但是z-index屬性值不為auto。

(3).伸縮專案Flex Item,且z-index值不為 auto,即父元素 display: flex|inline-flex。

(4).元素的opacity屬性值小於1。

(5).元素的 mix-blend-mode屬性值不為normal。

(6).元素的filter屬性值不為normal。

(7).元素的isolation屬性值為isolate。

(8).在will-change中指定了任意CSS屬性,即便你沒有定義該元素的這些屬性。

(9).元素的-webkit-overflow-scrolling屬性值為touch。

下面就通過程式碼例項對實際應用中常見的情況進行一下分析,為了節省空間,只給出了程式碼的核心部分。

沒有規定z-index屬性值:

[HTML] 純文字檢視 複製程式碼
<body>
    <div id="absdiv1">DIV #1</div>
    <div id="reldiv1">DIV #2</div>
    <div id="reldiv2">DIV #3</div>
    <div id="absdiv2">DIV #4</div>
    <div id="normdiv">DIV #5</div>
</body>

執行效果圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201702/05/132357o7zam73m7ek76lme.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

圖片說明:

(1).DIV#1和DIV#4是粉色框,position設定為absolute。

(2).DIV#2和DIV#3是綠色框,position設定為relative。

(3).DIV#5是黃色框,非定位元素。

DIV#5在最底層,因為它是非定位元素,即便它是DOM樹中的最後一個,但是它還是會被最先繪製。

其他元素由於都是定位元素,並沒有明確規定z-index屬性值,層疊順序在文件樹中靠後的,就在上層。

特別說明:完整文章可以查閱MDN對應文章。

浮動元素的層疊:

[HTML] 純文字檢視 複製程式碼
<div id="absdiv1">
    <br /><span class="bold">DIV #1</span>
    <br />position: absolute;
  </div>
 
  <div id="flodiv1">
    <br /><span class="bold">DIV #2</span>
    <br />float: left;
  </div>
 
  <div id="flodiv2">
    <br /><span class="bold">DIV #3</span>
    <br />float: right;
  </div>
 
  <br />
 
  <div id="normdiv">
    <br /><span class="bold">DIV #4</span>
    <br />no positioning
  </div>
 
  <div id="absdiv2">
    <br /><span class="bold">DIV #5</span>
    <br />position: absolute;
  </div>

執行效果圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201702/05/132508noawdiwdswovzm27.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

圖片說明:

(1).DIV#1和DIV#5是粉色框,position設定為absolute;

(2).DIV#2和DIV#3是綠色框,float設定分別為left和right,opacity是1;

(3).DIV#4是黃色框,非定位元素。

DIV#4是非定位元素,所以它的層級最低,會最先繪製,並且它並沒有建立一個新的層疊上下文,所以它的子元素<span>和DIV#1、DIV#2、DIV#3和DIV#5都是位於根元素建立的層疊上下文中;由於span是內聯元素,它的層疊級數要高於DIV#2浮動元素,所以DIV#2會先繪製,然後span元素再繪製,於是被擠到了右側。又因為定位元素層疊級數高於浮動元素,所以DIV#1和DIV#5會覆蓋在DIV#2和DIV#3之上。

特別說明:完整文章可以查閱MDN對應文章。

設定透明度:

使用的是上面的程式碼,只是將DIV#1,DIV#2,DIV#3,DIV#5的opacity設定為0.7。

執行效果圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201702/05/132636z4nusljaz6jp6cel.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

DIV#3的層級被提高到了DIV#1,規則如下:

(1).如果opacity小於1且未定位,則按其定位、z-index: 0 且 opacity: 1 的情況中的層疊順序繪製。

(2).如果opacity小於1且已定位,層疊順序就按照z-index值來確定,但是auto要視為0, 因為新的層疊上下文總是建立了的。

transform:

運用此屬性不但可以建立一個層疊上下文,而且還會改變定位元素的參考物件。

具體可以參閱transform變換可以改變定位元素的包含塊一章節。

相關文章