ie下的css層疊z-index各種問題詳細整理

到新地方有些日子了,差不多適應了這邊的工作節奏與流程 。接到的第一個開發任務是幾個比較簡單的頁面,需要做的工作就是先把設計圖變成頁面 , 然后使用PHP創建幾個請求的接口傳遞數據,標準且簡潔的web開發思路 。可是真有些日子沒有寫DIV CSS了,而且對IE6兼容性的坑碰到的還是不夠多(以前做國外項目),所以這次開發中不可避免的碰見了幾個問題 , 尤其是在IE下的 z-index 問題很有意思 , 所以整理了一些資料和總結分享給大家...注:因為引入了jsfiddle,所以頁面加載受影響會稍慢一些^_^
閱讀目錄:
z-index屬性
z-index規范參考
在IE下出現的問題
在IE6下z-index的問題拼爹的時代
萬惡的floatIE6下 select z-index無效而遮擋div用 iframe 包裹 select 元素
以 Iframe 作為div的子元素,覆蓋 select 元素本文結語z-index屬性
z-index : auto | numberz-index 屬性設置元素的堆疊順序,如果為正數,則離用戶更近,為負數則表示離用戶更遠;擁有更高堆疊順序的元素總是會處于堆疊順序較低的元素的前面;z-index 僅能在定位元素上奏效(position 屬性值為 relative 或 absolute 或 fixed的對象) 。z-index規范參考
在 W3C CSS2.1 規范中 , 每個元素都具有三維的空間位置 , 除我們所熟悉的水平和垂直位置外,元素還可在 Z軸 方向上層層相疊、依次向前排開;元素在 Z 軸 方向上的呈現順序,由層疊上下文和層疊級別決定 。在文檔中,每個元素僅屬于一個層疊上下文 。在給定的層疊上下文中,每個元素都有一個整型的層疊級別,它描述了在相同層疊上下文中元素在 Z軸 上的顯示順序;同一個層疊上下文中,層疊級別大的顯示在上 , 層疊級別小的顯示在下,相同層疊級別時,遵循后來居上的原則(back-to-font);不同層疊上下文中,元素顯示順序以父級層疊上下文的層疊級別來決定顯示的先后順序 。與自身的層疊級別無關;每一個定位元素都歸屬于一個stacking context 。根元素形成 root stacking context,而其他的 stacking context 則由定位元素產生(此定位元素的 z-index 被定義一個非 auto 的 z-index 值),定位子元素會以這個 local stacking context 為參考,用相同的規則來決定層疊順序;當任何一個元素層疊另一個包含在不同 stacking context 元素時,則會以 stacking context 的層疊級別(stack level)來決定顯示的先后情況 。也就是說 , 在相同的 stacking context 下才會用元素本身的 z-index 來決定先后,不同時則由 stacking context 的父元素的 z-index 來決定 。在IE下出現的問題
當定位元素的 ’z-index’ 未設置時(默認為 auto),在IE6 IE7 IE8(Q)下將會創建一個新的局部層疊上下文 。而在其它瀏覽器下,則嚴格按照規范 , 不產生新的局部層疊上下文 。
這個問題將導致定位元素的層疊關系在不同瀏覽器出現很大的區別,嚴重的可導致頁面布局混亂、內容覆蓋等 。
受影響的瀏覽器有IE6 IE7 IE8(Quriks Mode)
直接從w3help復制了代碼 , 分析以下代碼:

復制代碼代碼如下:
style type="text/css"
body { margin:0; }
.p1{ top:20px; height:50px; width:150px; background-color:blue;}
.p2{ top:10px; left:20px; height:30px; width:100px; background-color:yellow;}
.p3{ top:0px; left:50px; height:100px; width:50px; background-color:red;}
/style
div style="position:relative;" class="p1"1
div style="position:absolute; z-index:1;" class="p2"2/div
/div
div style="position:absolute;" class="p3"3/div

ie下的css層疊z-index各種問題詳細整理

注:Q代表Quriks Mode,即混雜模式 。
根據 W3C CSS2.1 規范中的說明,定位元素【p1】和【p3】由于未設置 ’z-index’ 特性(使用默認值 auto) , 它們不會創建新的局部層疊上下文,而定位元素【p2】設置了 z-index:1 則會創建新的層疊上下文 。
另,在同一根層疊上下文中,同為 z-index:auto 的定位元素【p1】和【p3】,它們的層疊級別相同,但【p3】在【p1】之后 , 所以在 Z 軸上【p3】比【p1】靠前顯示,又,【p2】層疊上下文的層疊級別為正數,所以【p2】的層疊級別要比【p3】高 。因此,它們在 Z 軸上的順序為:(遵循 back-to-font)【p1】 - 【p3】 - 【p2】
以上為標準瀏覽器下的情況 。
而在 IE6 IE7 E8(Q) 下 , 定位元素【p1】和【p3】都創建了新的局部層疊上下文,在同一根層疊上下文中,它們的層疊級別相同,但【p3】在【p1】之后 , 所以在 Z 軸上【p3】比【p1】靠前顯示 。此時,由于【p2】處于【p1】的層疊上下文中,所以【p2】在 Z 軸上要比【p3】靠后 。
在來一個例子:

復制代碼代碼如下:
style
.parent{width:200px; height:200px; padding:10px;}
.sub{text-align:right; font:15px Verdana;width:100px; height:100px;}
.lt50{left:50px;top:50px;}
/style
div style="position:absolute; background:lightgrey;" class="parent"
div style="position:absolute;z-index:20;background:darkgray;" class="sub"20/div
div style="position:absolute;z-index:10;background:dimgray;" class="sub lt50"10/div
/div
div style="position:absolute;left:80px;top:80px;background:black;" class="parent"
div style="position:absolute;z-index:2;background:darkgray;" class="sub"2/div
div style="position:absolute;z-index:1;background:dimgray;" class="sub lt50"1/div
/div

ie下的css層疊z-index各種問題詳細整理

解決辦法
理解層疊上下文、層疊級別與 ’z-index’ 之間的關系 。在可能出現定位元素相互覆蓋的情況時 , 明確指定定位元素的 ’z-index’ 特性,避免此問題的出現 。
注:此段內容基本都是來自w3help 。
在IE6下z-index的問題
我不是一個喜歡抱怨的人,so...有關抱怨IE6的話在此省略500字...
先上個圖說說我在工作中實際遇到的問題:
ie下的css層疊z-index各種問題詳細整理

圖片的上半部分就是在非IE6下的交互 , 圖片下半部分是在IE6下的顯示效果,當打開虛擬機測試的時候我表示瞬間碉堡了 , 囧...在IE6下這個tips被蓋住了,很明顯這個不是我想要的效果,可是為什么會出現這個情況類?接著往下看 。
分析此類問題的原因:
1.這是個拼爹的時代,在IE6下很好的體現了這點...囧
【ie下的css層疊z-index各種問題詳細整理】按照正常的思維 , z-index層級越高,內容越應該在上面顯示 , 在大部分的瀏覽器在大部分的情況下,確實如此,但是不絕對 。尤其遇到IE6 。
在IE6下的層級高低不僅要看本身,還要看自己的父元素是否給力:父元素的 position 屬性為 relative或absolute 時,子元素的 absolute 屬性是相對于父元素而言的 。而在IE6下的層級的表現有時候不是看子元素的 z-index 多高,而要看它們的父元素的 z-index 誰高誰低 。點擊 Result 可以看到HTML對應的VIEW 。
從以上的代碼中可以看到最內層div的z-index屬性為999,其父元素的z-index屬性為100 。按照正常的顯示邏輯,圖片應該正常顯示且不會被背景色所影響,可是在IE6下會有問題,直接上圖片會比較直觀,比較看看IE6下和非IE6瀏覽器的顯示效果 。chrome、FF和opera都經過測試了,為了不使圖片過多我就拿個chrome的截圖吧 。
ie下的css層疊z-index各種問題詳細整理

重現這個bug的條件很簡單,只要絕對定位(position:absolute)div的祖先元素,或者說是最頂級的祖先元素的 relative 屬性小于黑色半透明層的z-index層級即可 。解決辦法也很簡單 , 只需要給的祖先元素加上z-index就可以 。
ie下的css層疊z-index各種問題詳細整理

為具有 relative 屬性的頂級祖先元素打了雞血(加了z-index)后,IE6下終于正常顯示了 。這個問題很現實的教育了我們 - 在拼爹拼不過的條件下我們只能靠自己努力...
IE6下拼爹的問題也就是我在實際開發中碰到的問題 , 現在已經完美解決且達到需求的效果了 。接下來要介紹的是一些我總結的資料,都是介紹在IE環境下得各種z-index的坑 。
2.萬惡的float
float 是 css 的定位屬性,而且應該是CSS中最常用的屬性之一了,至于為什么說它萬惡等我改天去準備一篇文章單獨進行解說,在這里借著以前的學習筆記簡單說幾點:
1. IE7 中 , 底邊距 bug是當浮動父元素有浮動子元素時,這些子元素的底邊距會被父元素忽略掉;
2.3像素間距是指挨著浮動元素的文本會神奇的被踢出去3像素,好像浮動元素的周圍有一個奇怪的力場一樣;
3.雙倍邊距bug處理 IE6 時,另一個需要記住的事情是 , 如果在和浮動方向相同的方向上設置外邊距(margin),會引發雙倍邊距 。
有關float的掃盲就先到這里,還有一點就是float畢竟是標準的屬性,而且大多數的前端都習慣用它去實現頁面 , 所以我的建議就是:深入理解 HTML語義和表現 。
接著開始講述 z-index和float 在IE6環境下擦出的坑爹的火花...先上一段代碼:

復制代碼代碼如下:
div style="background:#000;width:100%;height:600px;opacity:0.3; filter:alpha(opacity=30);position:absolute;left:0;top:0;z-index:1;overflow:hidden;"/div
div style="position:relative;z-index:100;"
img src="https://www.questions.com.cn//imgup01.經驗啦網.net/經驗啦網/2018-03/28/13/15222152791171_6.jpg" style="float:left;" width="300" /
/div

看到img有設置float屬性,上面這段代碼顯示的效果與IE6下拼爹失敗一樣,IE6下的犀牛書是灰色的 T.T。為了讓犀牛書正常顯示,只需要把img的float屬性去掉即可 。個人理解可能是因為img的float使得z-index失效造成的 。網上還有種說法是因為float和relative兩者在定位上問題 , 所以一起使用的時候會造成此bug 。
這個問題又教育了我們 - 某些環境(IE6)下也要小心被兄弟坑...
IE6下 select z-index無效而遮擋div
這個問題其實在是比較常見的了,我早期做項目的時候有幸遇見過這個問題,所以有現成的資料 , 趁著這次也剛好整理整理、回憶回憶 。兩個解決辦法都是圍繞iframe展開的,咱們先來看第一個 。
1.用 iframe 包裹 select 元素
使用iframe包住select , 這樣iframe可以有z-index,只要在div上設置的z-index比iframe的高即可實現 。示例代碼如下:

復制代碼代碼如下:
iframe style="z-index:1;position: absolute; "
select name="me"
option value="https://www.questions.com.cn/dnjc/name"Darren聶微東/option
option value="https://www.questions.com.cn/dnjc/sex"male/option
option value="https://www.questions.com.cn/dnjc/age"secret/option
/select
/iframe

2.以 Iframe 作為div的子元素 , 覆蓋 select 元素(推薦使用)
建立一個跟div同寬同高的iframe,并且z-index比div要低 。

復制代碼代碼如下:
style type="text/css"
#iframe{
position: absolute;
width: 100%;
height: 100%;
z-index:-1;
}
.text_div{
position: absolute;
left:100px;
top:50px;
width: 300px;
height: 200px;
background : blue;
z-index:100;
}
/style
div class="text_div"
span這里可以包含其他dom元素/span
iframe id="iframe"/iframe
/div
注:在這里如果不加src屬性,盡管iframe會把select擋住,但是由于默認iframe為白色,會影響原來的div背景色 。解決方法可以加了一個空的HTML文件,并把body 的值設為和原來div背景色一致,這樣就解決了默認白色背景色的問題,這里只是一種思路 , 辦法總比困難多^_^ 。本文結語
與很多做國內項目的前端一樣,我也會常常忍不住詛咒IE,可是假如換個思考方式我們也得感謝它 , 工作因為它才有了更多挑戰和成就感 。
對不理解CSS層疊朋友來說z-index 確實是一個大坑,希望這篇文章能夠給那些掉到坑內的朋友一些幫助 。
如果覺得此文還算用心,請勞駕點擊右下角的推薦,謝謝^.^

相關經驗推薦