z-index詳解


轉自 https://www.cnblogs.com/JetpropelledSnake/p/9114270.html

前端學習筆記之Z-index詳解

 

CSS當中的z-index屬性看起來足夠簡單,但是如果你真的想了解它是如何工作的話,在這簡單的表面之下,又有許多值得探究的內容。 在這篇教程中,通過探究層疊上下文和一系列實際的例子,我們將會闡明z-index的內在機理。

CSS為盒模型的布局提供了三種不同的定位方案

  • 常規文檔流
  • 浮動
  • 絕對定位

其中最后一種定位方案將一個元素從常規流中移除,完全依賴開發者來確定元素顯示的位置。

通過賦予top, left, bottom 和 right 屬性值,可以在二維平面上放置元素,此外CSS也允許使用z-index屬性以在第三維上放置元素。

表面上,z-index看起來像是一個簡單的屬性。 你可以設置各種值來決定某一個元素會被置於第三維的何處,然后就完成了。 實際上,這其中還有許多許多可以研究的內容,包括確定哪一類元素會被放置到其他元素上的一些規則。

不如讓我們從基礎開始,以確保我們對此能有共同的理解。隨后,我們會談一些關於層疊的內容,以更好地理解在z-index的背后到底發生了什么。


我相信你一定對三維坐標空間很熟悉。 我們有x軸通常用來表示水平位置,y軸來表示垂直位置,還有z軸來表示在紙面內外方向上的位置,或者說在本文的語境下,屏幕內外方向上的位置。

3-Dimensional Coordinate Space
三維坐標空間

由於屏幕是一個二維平面,因此我們並不是真正地看到了z軸。 我們說看到z軸,其實是通過透視,通過元素展現在與其共享二維空間的其他元素的前面或者后面來看到的。

要確定沿着這z軸元素是如何分布的,CSS允許我們對z-index屬性設置三種值

  • auto (自動,默認值)
  • (整數)
  • inherit (繼承)

目前,先讓我們關注在整數值上。 整數值可以是正值,負值,或0。數值越大,元素也就越靠近觀察者。 數值越小,元素看起來也就越遠。

如果有兩個元素放在了一起,占據了二維平面上一塊共同的區域,那么有着較大z-index值的元素就會掩蓋或者阻隔有着較低z-index值的元素在共同區域的那一部分。

我想上面的邏輯非常易於理解,而且很有可能和你的預期是一致的。 盡管如此,現在還是有一些問題懸而未決、等待解答。

  • 當一個設置了z-index值的定位元素與常規文檔流中的元素相互重疊的時候,誰會被置於上方?
  • 當定位元素與浮動元素相互重疊的時候,誰會被置於上方?
  • 當定位元素被嵌套在其他定位元素中時會發生什么?

要回答這些問題,我們需要進一步地理解z-index是如何工作的,尤其是層疊上下文,層疊層,以及層疊次序這些概念。


層疊上下文和層疊層會有一些難以概念化,所以暫時讓我們想象一張桌子,上面有一堆物品。 這張桌子就代表着一個層疊上下文。 如果在第一張桌子旁還有第二張桌子,那第二張桌子就代表着另一個層疊上下文。

Stacking Contexts and Stacking Levels
層疊上下文1 (Stacking Context 1)是由文檔根元素形成的。 層疊上下文2和3 (Stacking Context 2, 3) 都是層疊上下文1 (Stacking Context 1) 上的層疊層。 他們各自也都形成了新的層疊上下文,其中包含着新的層疊層。

現在想象在第一張桌子上有四個小方塊,他們都直接放在桌子上。 在這四個小方塊之上有一片玻璃,而在玻璃片上有一盤水果。 這些方塊、玻璃片、水果盤,各自都代表着層疊上下文中一個不同的層疊層,而這個層疊上下文就是桌子。

每一個網頁都有一個默認的層疊上下文。 這個層疊上下文(桌子)的根源就是html元素。 html標簽中的一切都被置於這個默認的層疊上下文的一個層疊層上(物品放在桌子上)。

當你給一個元素賦予了除 auto (自動) 外的z-index值時,你就創建了一個新的層疊上下文,其中有着獨立於頁面上其他層疊上下文和層疊層的層疊層。 這就相當於你把另一張桌子帶到了房間里。


最容易理解層疊次序的方法就是用一個簡單的例子來說明,這個例子會簡單到我們甚至暫時不考慮定位元素

想象一張非常簡單的網頁。 除了默認的<html><head><body>之類的元素,你會發現在每個頁面上都有那么一個<div>元素。 在你的CSS文件中,你給html元素設置了藍色的背景顏色。 對於div元素,你設置了寬高和紅色的背景顏色。

那么在你加載頁面的時候,你會期望看到什么呢?

希望這不會花你很多時間來想象出一幅幾乎全是藍色的屏幕,除了上面有一塊紅色的方塊,這個方塊有着你設置的寬和高。 這個紅色方塊應該會出現在頁面的左上角,除非你比較有想象力,給這個方塊設置了額外的css來把它顯示在其他地方。

 

 

你也許會想“那又怎樣呢?這不是很明顯嘛”,但是不那么明顯的是為什么你會在藍色的背景上看到有一個紅色的方塊。 為什么你會看到div元素在html元素上方? 原因就是他們都遵循着層疊次序的規則。

比如在這個簡單的例子中,規則規定常規流(例子中的div)中的子塊會被置於根元素(例子中的html元素)的背景和邊框之上。 你會看到div元素在最上面是因為它在更高的層疊層上。

盡管上面給出的例子只包含了一個兩級的層疊,事實上在一個層疊上下文中一共可以有7種層疊等級,列舉如下:

  1. 背景和邊框 —— 形成層疊上下文的元素的背景和邊框。 層疊上下文中的最低等級。
  2. 負z-index值 —— 層疊上下文內有着負z-index值的子元素。
  3. 塊級盒 —— 文檔流中非行內非定位子元素。
  4. 浮動盒 —— 非定位浮動元素。
  5. 行內盒 —— 文檔流中行內級別非定位子元素。 行內盒在塊級盒上 所以能看到div上面的文字
  6. z-index: 0 —— 定位元素。 這些元素形成了新的層疊上下文。
  7. 正z-index值 —— 定位元素。 層疊上下文中的最高等級。

Stacking Order
層疊上下文中的七種層疊等級

這七個層疊等級構成了層疊次序的規則。 在層疊等級七上的元素會比在等級一至六上的元素顯示地更上方(更靠近觀察者)。 在層疊等級五上的元素會顯示在等級二上的元素之上。 在...上的元素會... 好吧,我想你已經明白了。

我在第一次碰上上面的層疊次序規則時想到一些事情。 如果你只看層疊等級2, 6, 7(那些提到了z-index的等級),很有可能你會發現這和你對於z-index的理解相符。 正z-index值比0 z-index值更高一層,0 z-index值又比負z-index值高一層。 盡管這也很有可能是我們大部分人停止思考關於這些層疊層的地方。

在見到這些規則之前我還以為一切其他東西都和0值z-index是一樣的呢。很顯然事實並非如此。 事實上,大多數的一切都比z-index為0的層疊等級低。

另外同樣有趣的是非定位元素分散在四個不同的層疊等級上。 不過當你思考起來就會發現這有道理。 如果所有的非定位元素都在同一層疊等級上,那么我們就不會看到文字(行內盒)在div上了(塊級盒)。


文章里我多次提到創建形成新的層疊上下文。 當你將除了auto以外的z-index值賦給一個元素,你就創建了一個新的層疊上下文,它獨立於其他的層疊上下文。

讓我們再次把桌子當作層疊上下文來考慮。 之前,我們有一張桌子,桌子上有四個方塊、一片玻璃和一盤水果。 想象在這第二張桌子上也有四個同樣大小的方塊,方塊上有一片玻璃,不過沒有水果盤。

你一定會想第一張桌子上的水果盤是房間里最高的東西了。 因為它在最高的層疊層上(有着最大的z-index值)。 但要是我們把第一張桌子和這張桌子上的一切東西放到地下室去呢? 那么水果盤現在就會比所有在第二張桌子上的東西低了,因為第一張桌子本身已經被移到比第二張桌子低的層疊層去了。

對於網頁上的定位元素來說也是同樣。 考慮如下網頁和樣式。 div.two會顯示在div.four上面還是下面呢?

HTML:

CSS:

復制代碼
div {
  width: 200px;
  height: 200px;
  padding: 20px;
}
 
.one, .two, .three, .four {
  position: absolute;
}
  
.one {
  background: #f00;
  outline: 5px solid #000;
  top: 100px;
  left: 200px;
  z-index: 10;
}
  
.two {
  background: #0f0;
  outline: 5px solid #000;
  top: 50px;
  left: 75px;
  z-index: 100;
}
 
.three {
  background: #0ff;
  outline: 5px solid #000;
  top: 125px;
  left: 25px;
  z-index: 150;
}
 
.four {
  background: #00f;
  outline: 5px solid #ff0;
  top: 200px;
  left: 350px;
  z-index: 50;
}
復制代碼

 

 

盡管div.two有着更大的z-index (100),它實際上比同一頁面上的div.four (z-index為50) 位置更低。 你可以在下面的圖中看到上面代碼的結果。 黑色和黃色的邊框表示着每個元素所處的不同的層疊上下文。

stacking

由於div.two被包含在div.one中,它的z-index值也是相對於div.one的層疊上下文來說的 事實上,我們真正得到的是如下結果:

  • .one — z-index = 10
  • .two — z-index = 10.100
  • .three — z-index = 10.150
  • .four — z-index = 50

我們所做的其實是把div.one和它所包含的一切放在了div.four之下。 不管我們給div.one中的元素設置了什么z-index值,他們永遠都會顯示在div.four的下面。

如果你像我一樣,這可能在你處理z-index的時候已經坑了你一兩次。 希望這些例子能幫助你厘清為什么有時一個有着較大z-index值的元素卻顯示在只有較小z-index值的元素的后面。

如果去掉父元素z-index,子元素z-index就不會受到父元素限制


當你初次遇到z-index時,它就像一個非常簡單、易於理解的屬性。 它的值代表着在朝向屏幕內外的軸上的位置,沒有別的。

深入探究z-index揭示出在z-index的背后,還發生了許多事情。 包括層疊上下文、層疊層和確定哪個元素在上哪個元素在下的層疊次序規則。

定位元素還會產生新的層疊上下文,而這整一個層疊層會顯示在另一個層疊上下文中的所有層疊層的上面或者下面。


 

參考

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM