z-index使用詳解元素重疊及position定位
阿新 • • 發佈:2019-01-01
z-index使用詳解,JavaScript教程網為您講解如何使用 CSS 的 z-index 屬性,淺析CSS——元素重疊及position定位的z-index順序。
多次在專案中遇到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
<div class="pr" id="one">
#one相對定位
<div class="pa pa1">#one的子元素pa1,相對#one絕對定位,#one是它的父元素,與.pa2為同級兄弟元素
<div class="pa pa2">#one的子元素pa2,相對#one絕對定位,#one是它的父元素,與.pa1為同級兄弟元素
<div class="pa" id="two">#two絕對定位,與#one為同級元素
預設
均未加z-index值
.pr{position:relative;}
.pa{position:absolute;}
div{width:200px;height:200px;border:1px solid #ccc;color:#fff;font:bold 14px fae8f6f96c59ed1;}
#one{background:#39f;}
#one .pa1{background:#096;top:25px;left:20px;}
#one .pa2{background:#969;top:90px;left:40px;}
#two{background:#669;top:165px;left:70px;}
表現及解析
定位後依照元素在文件中的先後位置,後出現的會在上面。
相對性試驗
為#one加上z-index:1;#one .pa1加上z-index:30;#one .pa2加上z-index:20;#two加上z-index:9;
.pr{position:relative;}
.pa{position:absolute;}
div{width:200px;height:200px;border:1px solid #ccc;color:#fff;font:bold 14px fae8f6f96c59ed1;}
#one{background:#39f; z-index:1;}
#one .pa1{background:#096;top:25px;left:20px; z-index:30;}
#one .pa2{background:#969;top:90px;left:40px; z-index:20;}
#two{background:#669;top:165px;left:70px; z-index:9;}
表現及解析
因為父輩同級元素的z-index值#one<#two,所以#one決定了其子元素.pa1和.pa2的z-index值不論有多大都會被#two所覆蓋;作為同級兄弟元素的.pa1和.pa2則比較其z-index值,較大的.pa1顯示在上面。
ie6、7相容性試驗
為#one .pa1加上z-index:10;#two加上z-index:1;
表現及解析
Firefox/Chrome等現代瀏覽器(包括ie8+)下,父元素#one未設定z-index值,則預設為auto,此時的#one .pa1為自由的定位元素,因此z-index較大的#one .pa1顯示在較小的#two上面。如果把#two的z-index值去掉,情況也會是一樣的,設定了較大z-index值的#one .pa1會顯示在未設定z-index的元素上面。
ie6/7下,差異在於#one .pa1顯示在了#two的下面。因為對於ie6/7父元素#one未設定z-index值,會被隱含設定了z-index:0;此時z-index值#one的0要與#two的1比較,而#two比較大,所以#one的子元素無論z-index如何的大也會被#two遮擋。如果把#two的z-index值去掉,情況依舊,因為未設定z-index值的#one和#two都會被預設加上z-index:0;有了值就可以比較,值相同的情況下堆疊順序由元素在文件中的先後位置決定,出現在後面的#two會在上面,結果#one的子元素無論z-index如何的大還是會被#two遮擋。
2012040114074097.jpg (50.8 KB, 下載次數: 0)
多次在專案中遇到html頁面元素的非期待重疊錯誤,多數還是position定位情況下z-index的問題。其實每次解決類似問題思路大致都是一樣的,說到底還是對z-index的理解比較模糊,可以解決問題卻不大瞭解其原因,導致重複出錯......於是決定把重疊問題弄清下,把z-index理順下。
經過一番查詢對比實踐理解,下面就從元素重疊的背景常識及可能原因說起,淺談下position定位元素的z-index順序。總結下我目前的理解,希望也能對遇到過類似問題有同樣疑惑的你有一點幫助或啟發。
元素位置重疊的背景常識
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
<div class="pr" id="one">
#one相對定位
<div class="pa pa1">#one的子元素pa1,相對#one絕對定位,#one是它的父元素,與.pa2為同級兄弟元素
<div class="pa pa2">#one的子元素pa2,相對#one絕對定位,#one是它的父元素,與.pa1為同級兄弟元素
<div class="pa" id="two">#two絕對定位,與#one為同級元素
預設
均未加z-index值
.pr{position:relative;}
.pa{position:absolute;}
div{width:200px;height:200px;border:1px solid #ccc;color:#fff;font:bold 14px fae8f6f96c59ed1;}
#one{background:#39f;}
#one .pa1{background:#096;top:25px;left:20px;}
#one .pa2{background:#969;top:90px;left:40px;}
#two{background:#669;top:165px;left:70px;}
表現及解析
定位後依照元素在文件中的先後位置,後出現的會在上面。
2012040113460968.png (9.58 KB, 下載次數: 0)
相對性試驗
為#one加上z-index:1;#one .pa1加上z-index:30;#one .pa2加上z-index:20;#two加上z-index:9;
.pr{position:relative;}
.pa{position:absolute;}
div{width:200px;height:200px;border:1px solid #ccc;color:#fff;font:bold 14px fae8f6f96c59ed1;}
#one{background:#39f; z-index:1;}
#one .pa1{background:#096;top:25px;left:20px; z-index:30;}
#one .pa2{background:#969;top:90px;left:40px; z-index:20;}
#two{background:#669;top:165px;left:70px; z-index:9;}
表現及解析
因為父輩同級元素的z-index值#one<#two,所以#one決定了其子元素.pa1和.pa2的z-index值不論有多大都會被#two所覆蓋;作為同級兄弟元素的.pa1和.pa2則比較其z-index值,較大的.pa1顯示在上面。
2012040114434229.jpg (37.53 KB, 下載次數: 0)
ie6、7相容性試驗
為#one .pa1加上z-index:10;#two加上z-index:1;
表現及解析
Firefox/Chrome等現代瀏覽器(包括ie8+)下,父元素#one未設定z-index值,則預設為auto,此時的#one .pa1為自由的定位元素,因此z-index較大的#one .pa1顯示在較小的#two上面。如果把#two的z-index值去掉,情況也會是一樣的,設定了較大z-index值的#one .pa1會顯示在未設定z-index的元素上面。
ie6/7下,差異在於#one .pa1顯示在了#two的下面。因為對於ie6/7父元素#one未設定z-index值,會被隱含設定了z-index:0;此時z-index值#one的0要與#two的1比較,而#two比較大,所以#one的子元素無論z-index如何的大也會被#two遮擋。如果把#two的z-index值去掉,情況依舊,因為未設定z-index值的#one和#two都會被預設加上z-index:0;有了值就可以比較,值相同的情況下堆疊順序由元素在文件中的先後位置決定,出現在後面的#two會在上面,結果#one的子元素無論z-index如何的大還是會被#two遮擋。
2012040114524056.jpg (70.59 KB, 下載次數: 0)
簡單總結及建議普通元素的堆疊順序由元素在文件中的先後位置決定,後出現的會在上面,請小心計算好浮動和負邊距佈局,注意視窗元素的特殊性;非同級關係和非父子關係定位元素之間的堆疊順序,要向上追溯到其為兄弟關係的父元素上,先比較其z-index值,只有父輩元素中的z-index值較大的後代子元素才能超過z-index值較小的父輩元素及其子孫元素。
為了在編碼時就減少z-index值判斷的複雜性,我建議對於一般頁面內容類定位元素的z-index設定小於99的值(如非必要不使用負值),廣告類定位元素的z-index設定100~500的值,公告提示等彈出類定位元素的z-index設定大於500的值;對於比較複雜定位巢狀頁面,為了避免ie6/7的顯示差異,請為父輩類定位元素顯性加上z-index:0或其他值。
以上是我目前網路搜尋書籍參考結合實踐後的理解總結,如有錯誤,請不吝賜教;如有疑問,歡迎討論;如有幫助,萬分榮幸;如有雷同,握個手吧~