DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> CSS入門知識 >> CSS詳解 >> 深入解析CSS中z-index屬性對層疊順序的處理
深入解析CSS中z-index屬性對層疊順序的處理
編輯:CSS詳解     
這篇文章主要介紹了CSS中z-index屬性對層疊順序的處理,分情況講解了各種曾跌情況下哪個box更靠近用戶,需要的朋友可以參考下

多次在項目中遇到Html頁面元素的非期待重疊錯誤,多數還是position定位情況下z-index的問題。其實每次解決類似問題思路大致都是一樣的,說到底還是對z-index的理解比較模糊,可以解決問題卻不大了解其原因,導致重復出錯......於是決定把重疊問題弄清下,把z-index理順下。

經過一番查找對比實踐理解,下面就從元素重疊的背景常識及可能原因說起,淺談下position定位元素的z-index順序。總結下我目前的理解,希望也能對遇到過類似問題有同樣疑惑的你有一點幫助或啟發。

元素位置重疊的背景常識

(x)Html文檔中的元素默認處於普通流(normal flow)中,也就是說其順序由元素在文檔中的先後位置決定,此時一般不會產生重疊(但指定負邊距可能產生重疊)。當我們用CSS為某個元素指定float浮動或者position定位後,元素的定位將會依情況發生如下改變:

1. 指定float值left/right

行內元素也會隱形變成塊元素,元素會脫離文檔的普通流,向左或右浮動,直到其外邊緣碰到包含框或另一個浮動框。

2. 指定position值relative

可以相對於其在普通流中的位置偏移,原本所占的空間仍保留。

3. 指定position值absolute

行內元素也會隱形變成塊元素,元素會脫離文檔的普通流,相對於最近的已定位祖先元素偏移,如果元素沒有已定位的祖先元素,那麼它的位置相對於最初的包含塊偏移。

4. 指定position值fixed

元素會脫離文檔的普通流,相對於浏覽器窗口偏移,固定在浏覽器的某個位置。

以上四種情況下,文檔中的元素都將可能被浮動/定位元素覆蓋產生重疊。

元素位置重疊的可能原因

1. 負邊距/float浮動

margin為負值時元素會依參考線向外偏移。margin-left/margin-top的參考線為左邊的元素/上面的元素(如無兄弟元素則為父元素的左內側/上內側),margin-right和margin-bottom的參考線為元素本身的border右側/border下側。一般可以利用負邊距來就行布局,但沒有計算好的話就可能造成元素重疊。堆疊順序由元素在文檔中的先後位置決定,後出現的會在上面。

浮動元素會脫離文檔的普通流,有可能覆蓋或遮擋掉文檔中的元素。

2. position的relative/absolute/fixed定位

當為元素設置position值為relative/absolute/fixed後,元素發生的偏移可能產生重疊,且z-index屬性被激活。z-index值可以控制定位元素在垂直於顯示屏方向(Z 軸)上的堆疊順序(stack order),值大的元素發生重疊時會在值小的元素上面。

3. window窗口元素引發的重疊

浏覽器解析頁面時,先判斷元素的類型:窗口元素優於非窗口元素顯示(也就是窗口元素會覆蓋在其它非窗口元素之上),同為非窗口類型才能在激活z-index屬性控制堆疊順序。

Flash元素屬於window窗口元素

所以如果頁面上flash元素和其他元素發生重疊,需要先將Flash嵌入的wmode屬性的window(窗口,默認的會造成上面所說的問題)改為非窗口模式:opaque(非窗口不透明)或者 transparent(非窗口透明)。

IE6下select屬於window類型控件

同理,它也產生窗口元素的遮擋問題。解決方法使用iframe(原理:IE6下普通元素無法覆蓋select,iframe可以覆蓋select,普通元素可以覆蓋iframe)/用div模擬實現select的效果。我一般會為被select遮擋的div在內部追加(appendChild)一個空的子iframe,設置position:absolute脫離文檔流空間、width:100%;height:100%;覆蓋整個父div、z-index:-1;確保值要小於父div的z-index值讓父div覆蓋顯示在iframe上面,借助這個iframe來覆蓋select。

淺說position定位及z-index使用

使用前提

z-index只能在position屬性值為relative或absolute或fixed的元素上有效。

基本原理

z-index值可以控制定位元素在垂直於顯示屏方向(Z 軸)上的堆疊順序(stack order),值大的元素發生重疊時會在值小的元素上面。

使用的相對性

z-index值只決定同一父元素中的同級子元素的堆疊順序。父元素的z-index值(如果有)為子元素定義了堆疊順序(CSS版堆疊“拼爹”)。向上追溯找不到含有z-index值的父元素的情況下,則可以視為自由的z-index元素,它可以與父元素的同級兄弟定位元素或其他自由的定位元素來比較z-index的值,決定其堆疊順序。同級元素的z-index值如果相同,則堆疊順序由元素在文檔中的先後位置決定,後出現的會在上面。

所以如果當你發現一個z-index值較大的元素被值較小的元素遮擋了,請先檢查它們之間的dom結點關系,多半是因為其父結點含有激活並設置了z-index值的position定位元素。

也因為這個相對性,還會引發浏覽器表現不一致出現兼容問題。原因是IE6、7下面position值為非static的元素在未設置z-index值的情況下都會被隱含添加z-index:0,而Firefox/Chrome等現代浏覽器會遵循標准默認z-index:auto不會產生值。

還有一點需要注意,負值的z-index也依照大小比較的原理,但一般來說負值的z-index會被透明的body覆蓋導致點擊等事件響應出現問題,請謹慎使用。

圖解分層顯示

其實我們常接觸到的z-index只是分層顯示中的一個屬性而已,而理解z-index背後的原理實質上就是要理解分層顯示原理。下面我們通過一個示例來認識一下分層顯示涉及的對象和屬性(z-axis、(root) stacking context、box、stack level)以及它們之間的關系。

Html Markup

201635111602370.png (1030×712)

說明:

1. 在構造渲染樹時會為element生成對應的box,所以div#d1->d1:box,div#d2->d2:box,div#d3->d3:box,div#d4->d4:box,p#p1->p1:box。

2. 對於positioned box而言,若z-index屬性值不是0,則會創建一個新的stacking context,並且其子孫box將屬於這個新stacking context。

3. 同一個stacking context的z-index才具有可比性,也就是說在討論z-index時必須帶說明是哪個stacking context下的z-index。如示例般,雖然-9999比10小,但由於d4:box和d1:box位於不同的stacking context,因此無法判斷哪個box更靠近用戶。

層疊規則                          

層疊規則就是決定到底哪個box更靠近用戶。

1. 前提:boxes屬於同一個stacking context,並且z-index相同

規則:按照box對應的element在文檔樹的順序,後者比前者更靠近用戶(back-to-front)

CSS Code復制內容到剪貼板
  1. <!-- 兩種情況下,d2均排在d1的後面,因此d2在z-axis上位於d1的上面 -->
  2. <div id="d1">
  3. <div id="d2">
  4. </div>
  5. </div>
  6. <div id="d1">
  7. </div>
  8. <div id="d2">
  9. </div>

2. 前提:boxes屬於同一個stacking context,並且z-index不同

規則:z-index屬性值大的box更靠近用戶

CSS Code復制內容到剪貼板
  1. <!-- d1的z-index為12,而d2的z-index為0,所以d1在d2的上面 -->
  2. <div id="d1" style="position:relative;z-index: 12;">
  3. </div>
  4. <div id="d2" style="z-index: 0;margin-top:-20px;">
  5. </div>

3. 前提:boxes屬於不同的stacking context,並且stacking contexts沒有祖孫/父子關系

規則:boxes會向上沿著父box進行搜索,直到父boxes屬於同一個stacking context為止,然後比較父boxes的z-index屬性值,z-index屬性值大的box更靠近用戶。

CSS Code復制內容到剪貼板
  1. <div>
  2. <div id="d1" style="position:relative; z-index:10;">
  3. <div id="d4" style="background:red; width:100px; height:100px;position:relative; z-index:9999;">d3</div>
  4. </div>
  5. <div id="d2" style="background:blue; width:50px; height:50px; position:relative; top: -120px; z-index:9;">d2</div>
  6. <div id="d3" style="background:green; width:50px; height:50px; position:relative; top: -80px; position:relative; z-index:11;">d3</div>
  7. </div>

201635111849784.png (136×144)

4. 前提:boxes屬於不同的stacking context,並且stacking contexts為祖孫/父子關系

規則:屬於子stacking context的box必定更靠近用戶

CSS Code復制內容到剪貼板
  1. <div style="background:blue; width:100px; height:100px; position:relative; z-index:10;">
  2. <div style="background:red; width:50px; height:50px; position:relative; z-index:-10;"></div>
  3. </div>

201635111924924.png (113×110)

z-index的作用                        

啰嗦一句:同一個stacking context的z-index才具有可比性,也就是說在討論z-index時必須帶說明是哪個stacking context下的z-index。

它有兩個作用:1. 設置box在其所屬的stacking context下的stack level;

2. 當z-index屬性值非0時,則在該box中創建一個新的stacking context,而該box的子孫box默認屬於這個新stacking context。

注意:z-index的默認值為auto,自動賦值為0。因此默認情況下不會創建新的stacking context。

z-index生效的閥門

z-index屬性值僅對positioned box生效,而non-positioned box的z-index永遠為0。

也許你會舉出如下反例:

JavaScript Code復制內容到剪貼板
  1. <div id="d1" style="z-index:10;"></div>
  2. <script type="text/Javascript">
  3. console.log(window.getComputedStyle(document.getElementById('d1'))['zIndex']); // 輸出10
  4. </script>

但抱歉的是,上面獲取的是non-positioned element div#d1的z-index屬性值,而不是non-positioned box的z-index屬性值。

對於positioned element,它會將z-index賦予給對應的positioned box,而non-positioned element則不會。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved