1. 程式人生 > >CSS進階(16)—— CSS世界的層疊規則(下)

CSS進階(16)—— CSS世界的層疊規則(下)

  上一章我們主要了解了層疊上下文,層疊水平,CSS層疊領域的兩大黃金法則等概念,本章我們講繼續深入探索CSS世界的層疊規則。

1.深入理解層疊上下文

  “層疊上下文”的元素有如下的一些特性:

(1)預設層疊水平(z-index:auto)比普通元素要高

(2)可以阻斷元素的混合模式(CSS3混合模式mix-blend-mode/background-blend-mode簡介)

(3)可以巢狀,內部所有(層疊上下文及其所有普通子)元素均受制於外部的“層疊上下文”

(4)每個“層疊上下文”的元素和兄弟元素相互獨立,也就是說,當進行層疊變化或渲染的時候,只需要考慮後代元素

(5)每個“層疊上下文”的元素是自成體系的,當元素髮生層疊的時候,整個元素被認為是在父層疊上下文的層疊順序中(這點個人認為跟第二點表達的意思類似)

  上一章我們講了定位屬性可以幫助建立“層疊上下文”,那麼除了定位屬性外還有哪些CSS屬性或元素元素擁有層疊上下文呢?

(1)根層疊上下文

  根元素預設擁有層疊上下文,這可能跟頁面中如果沒有定位元素的話,預設會定位到根元素是一個道理,我們可以近似認為根元素的position預設值為relative,這也就很好的解釋了,為什麼頁面中所有元素至少處於一個“層疊結界”中。

(2)傳統層疊上下文(z-index不為auto且生效)

  在使用z-index屬性的時候,我們需要注意該屬性只能和某些CSS屬性搭配使用才會生效,在CSS2.1的世界中,我們只需要注意z-index需要搭配定位元素使用即可,然而在CSS3中,還有一些其他屬性也支援生成層疊上下文結界,等下我會列出這些屬性。在上一章節中,我測試並驗證了:z-index正值>z-index:0約等於z-index:auto>z-index負值。為什麼我要說z-index:0約等於z-index:auto。兩者的根本區別就在於是否會建立層疊上下文。z-index:auto是定位元素的預設屬性,該元素依舊是一個普通元素,而z-index:0是一個顯示宣告,在生效的情況下會給當前元素建立層疊上下文,這兩者在"層級別"的角度上講是一樣的,也就是他們的層疊水平相同(同級元素比較),但建立層疊上下文後會對內部元素產生較大的影響。乾巴巴的說了一大堆還是不明白?我們用測試驗證一下上面的說法。

 來看下面兩段程式碼產生的不同結果。

<div style="position:relative; z-index:auto;">
    <!-- 美女 -->
    <img src="1.jpg" style="position:absolute; z-index:2;">  
</div>
<div style="position:relative; z-index:auto;">
    <!-- 美景 -->
    <img src="2.jpg" style="position:relative; z-index:1;">  
</div>

<div style="position:relative; z-index:0;">
    <!-- 美女 -->
    <img src="1.jpg" style="position:absolute; z-index:2;">  
</div>
<div style="position:relative; z-index:0;">
    <!-- 美景 -->
    <img src="2.jpg" style="position:relative; z-index:1;">  
</div>

  兩段程式碼產生了完全不同的結果。當z-index:auto生效的時候,兩張圖片的父容器均為普通定位元素,因此圖片的z-index的參照物是最近的“層疊結界”(可能是根層疊上下文),由於美女圖的z-index>風景圖的,因此遵循"誰大誰上"原則。而當z-index:0生效的時候,兩張圖片的父容器均建立了層疊上下文,父容器在層疊水平上是同級的(均為z-index:0),因此遵循"後來居上"原則,此時內部的z-index屬於胳膊肘擰不過大腿的狀態,看起來就“失效了”。

(3)CSS3中的層疊上下文

  剛才提到了,CSS3中新增了一些可以直接建立層疊上下文的屬性,在這裡我標出我認為比較搞的屬性,並羅列其他屬性。CSS3的內容本章不多做展開,恕我直言,我也不會。

  1.z-index值不為auto的flex項(父元素display:flex|inline-flex).
  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.

  這裡我單獨拿出第二條說明一下,注意這裡的說明是opacity不是1,在我們做顏色漸變的特效的時候,往往元素的初始狀態是opacity為1,過渡到一個<1的值,然而這個變化會會使得元素的層級有意想不到的情況發生,因此需要注意在做透明度過度的時候儘量設定元素本身的opacity為0.99這樣的近似值。

(4)層疊上下文與層疊順序

  

  上一章我在講層疊順序的時候給出了這樣一張圖,這裡我們需要注意的是,只要能生成z-index:auto的CSS屬性,就有可能會影響層疊順序,除了比較好記的定位元素外,我們還需要注意CSS3新增的一些屬性,尤其是我剛才提到的opacity不為1的屬性,只要能讓z-index:auto屬性生效的元素,就會提升自身元素的層級,這是一個注意點,單獨講一下加深印象。

2.z-index負值理解與使用

  z-index是支援負值的,在z-index負值生效的時候,該元素的層級在當前層疊上下文中僅比backgroud/border等裝飾品的層級高一級,可以認為是“最低”的。通常我們需要某個元素部分隱藏的時候可以用到z-index:負值。在使用z-index的負值屬性的時候,需要注意一個點,z-index屬性會去找第一個層疊上下文元素作為層疊結界,因此我們在使用的時候要相當注意當前z-index生效的元素的層疊結界是誰。可以說,沒有明確層疊結界的z-index都是耍流氓。(我說的明確不是瀏覽器明確,而是你自己要知道層疊結界在哪裡,瀏覽器可不會犯糊塗)

  我們通過一個例子加深一下印象。

<!-- z-index負值 -->
<div class="box">
	<div class="content">我被隱藏了</div>
</div>
<style>
.box{
	width: 200px;
	height: 200px;
	background: rgb(255,255,0);
}
.content{
	width: 300px;
	height: 300px;
	background: rgb(0,255,255);
	position: relative;
	z-index: -1;
}
</style>

  

  可以看到文字不見了,content元素的被box遮擋了一部分內容,這是因為兩者的預設層疊結界都是根層疊結界,因此content的層級要比box的低,就被覆蓋了。如果我們給box加上一個層疊結界呢?

<!-- z-index負值 -->
<div class="box">
	<div class="content">我被隱藏了</div>
</div>
<style>
.box{
	width: 200px;
	height: 200px;
	background: rgb(255,255,0);
	position: relative;
	z-index: 0;
}
.content{
	width: 300px;
	height: 300px;
	background: rgb(0,255,255);
	position: relative;
	z-index: -1;
}
</style>

  

  可以看到結果已經完全不同了,此時content的z-index:-1找到了第一個層疊結界是box元素,因此不管z-index有多大的負值,都不可能超過這個結界,我們可以看到,content元素覆蓋了box的背景色。

  利用z-index負值可以隱藏元素的特性,我們可以完成可訪問性隱藏,只需要層疊上下文內某一個父元素加個不透明的背景色就可以了,他與clip相比的優勢是無需絕對定位,而他的不足之處就是不具有普遍適用性,需要其他元素配合進行隱藏,說白了,就是維護成本高了,別人不知道你為什麼這樣做。

  

   本章關於z-index的內容就到這兒了,這裡做個總結。

(1)任何元素都擁有自己的層疊規則,要找到某一元素在z軸上的位置,就要先找他的層疊結界。

(2)記住“誰大誰上”,“後來居上”的黃金法則。

(3)遇到元素隱藏問題,不放檢查下層疊結界的設定是否合理。

  下一章的內容是CSS強大的文字處理能力,感興趣的同學可以點個關注。