切圖系列:W3C奇技淫巧之層疊上下文

w3c規範裏的stacking context,譯做層疊上下文,最主要的做用仍是用來比較一個擁有定位元素(position:!static)的元素的z軸層疊關係(z-index)。css

先上一個經典的例子:html

http://jsbin.com/pupibo/11/edit][1]web

代碼:wordpress

html:flex

<div><span id="a">A z-index:1;</span></div>
  <div><span id="b">B</span></div>
  <div><span id="c">C</span></div>

cssspa

#a,#b,#c{
  position:absolute;
  width:200px;
  height:100px;
}
#a{
  left:20px;
  top:20px;
  background:yellow;
  z-index:1;
}
#b{
  left:50px;
  top:50px;
  background:pink;
}
#c{
  left:80px;
  top:80px;
  background:cyan;
}

效果:code

demo 1

問題:在不給#b #c設置z-index的狀況下,如何讓#a置於其餘二者的後面?orm

答案你知道的,給包裹#adiv增長樣式:htm

div:first-of-type{
    opacity:0.9999;
  }

其實這裏就涉及到堆疊上下文的概念了。context這個名詞在css相關規範裏見得多了,最著名的有塊級格式上下文(block formatting context)。那麼什麼是上下文(context)呢?按個人理解,應該是某種相似環境的東西,一旦一個元素被加入一個context,他們的某些屬性值會放在一塊兒比較,最終的比較結果會影響到他們的視覺呈現。ci

而處於同一個堆疊格式上下文內的元素,它們會相互比較本身在z軸疊放的順序,從而知道誰應該在誰的上面、誰應該在誰的下面(貴圈真亂 (。・д・。) ):

  • 同一個層疊上下文中,層疊級別(即z-index屬性值)大的顯示在上面,反之顯示在下面。

  • 同一個層疊上下文中,層疊級別相同的兩個元素,依據它們在HTML文檔流中的順序,寫在後面的將會覆蓋前面的。

那麼問題來了,可不可能產生一個新的層疊上下文?

固然可能,根據規範,如下狀況將會產生一個新的層疊上下文:

  • 當一個元素是文檔的根元素時,在完整的html文檔裏,根元素是html標籤;

  • 當元素擁有一個值爲非staticposition且擁有一個值爲非autoz-index樣式時;

  • 當元素擁有一個值小於1opacity樣式時;

  • 當元素擁有一個值不爲none且有效的transform樣式時;

  • 當元素擁有一個值爲display:flex|inline-flex的樣式且z-index不爲auto時;

  • 當元素擁有一個值不爲normalmix-blend-mode樣式時;

  • 當元素擁有一個值爲isolateisolation樣式時;

  • 當元素的will-change樣式指定爲上述任意一個值時;

  • 在移動端,當元素擁有一個值爲touch-webkit-overflow-scrolling值時;

  • 當元素的filter(此處爲CSS3的濾鏡)值不爲none時;

  • IE6,7 下,當元素擁有一個值爲非staticposition的樣式時,即便z-index未定義。

所以,元素的層疊關係不只與它在堆疊上下文中所屬的層疊級別有關,還與它所在的堆疊上下文的順序有關。這就是上面例子的所有祕密。而前文中的例子,其實還有另外一種方法,對,給div:first-of-type添加transform:transform-function樣式。

最後,看到特意給ie6/7加粗的那條了嗎?嗯,這就是ie6/7那個著名bug的根源,具體bug解剖請看張鑫旭大大2009年的一篇文章:ie6下z-index犯癲不起做用bug的初步研究,或者@doyoe的這個簡單的demo

最後附上這道題答案的效果:

http://jsbin.com/pupibo/12

效果圖:

demo 2

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息