瀏覽器兼容之旅第三站:IE常見Bug總結及修復方法—part1
Internet Explorer前端攻城師的的惡夢,十個有九個前端人員都認為他為禍人間不淺,本應早點滅掉他,可是上天有好生之德,因而沒有滅之,在此情況下,前端的攻程師們將就將就過吧 。前面在《瀏覽器兼容之旅第一站:如何在頁面中創建IE條件注釋》和《瀏覽器兼容之旅第二站:各瀏覽器的Hack寫法讓瀏覽器達到一致的渲染效果》中了解了一些處理兼容的基本方法 。那么這節開始瀏覽器兼容之旅的第三站:IE常見Bug,在本節中 , 您可以了解IE中常見的Bugs , 以及這些Bugs要如何去避免發生 , 或者發生了,我們將如何去解決他 。大家有興趣嗎?有興趣的童鞋們就開始我們的旅行吧 。
一、浮動元素的雙倍Margin的Bug
浮動元素的雙倍Margin的Bug是IE6以及其以下版本的一個經典Bug了 , 觸發這個Bug的產生是給元素設置了float并且同時和float同一方向設置了margin值 , 此時在IE6(IE6以下版本我們飄過不理了)就會產一個雙倍margin值的Bug 。我們先來看一段代碼:
復制代碼代碼如下:
.demo {
background: #95cfef;
border: 1px solid #36f;
float: left;
height: 100px;
margin: 30px 0 0 30px;
width: 300px;
}
效果

修復方法
修復這個立王Bug的方法很簡單 , 只需要改變浮動元素的顯示風格,也就是說在浮動元素中增加一個display:inline屬性,這樣就可以輕松的解決浮動元素的雙倍Margin的Bug 。下面是修改后的代碼:
復制代碼代碼如下:
.demo {
background: #95cfef;
border: 1px solid #36f;
display: inline;
float: left;
height: 100px;
margin: 30px 0 0 30px;
width: 300px;
}
二、克服Box Model的Bug
Box Model的Bug常發生在同時給一個元素設置了寬度和高度的時候還設置了元素的padding或border值,此時將改變元素的真正大小 。換個形像一點的例子,我們進行行一個960px的布局,里面左邊欄是220px的寬度 , 主內容是720px的寬度,他們之間是20px的間距,此時設計需要在左邊欄有一個10px左右內距,如果我們按下面的代碼寫就會產生一個Bug 。
Html markup
復制代碼代碼如下:
div id="wrap"
div id="left" left/div
div id="content" main/div
/div
CSS Code
復制代碼代碼如下:
#wrap {
width: 960px;
background: #66CCFF
}
#left {
background: #FFCC99;
float: left;
padding: 0 10px;
width: 220px;
}
#right {
background: #9933CC;
float: right;
width: 720px;
}
此時div#left將改變了其實際的寬度 , 我們來看下面的一個圖 , 上圖是沒有padding值時的div#left,而下圖是有padding的div#left:

這個Bug在所有瀏覽器都將存在 , 因為在div#left中padding值改變了最初的寬度220px,那么要克服這個Bug也不難 , 只需要在div#left內部增加一個div,并把padding值移入到這個新增加的div中就行了 。
復制代碼代碼如下:
div id="wrap"
div id="left"
divleft/div
/div
div id="content" main/div
/div
CSS Code
復制代碼代碼如下:
#wrap {
width: 960px;
background: #66CCFF
}
#left {
background: #FFCC99;
float: left;
width: 220px;
}
#left div {
padding: 0 10px;
}
#right {
background: #9933CC;
float: right;
width: 720px;
}
此例只說加了padding值,如果在div中加了border值,我們同樣需要把border值也移入到內部的div中 , 這樣就可以輕松克服Box Model帶來的Bug 。當然不增加額外標簽也有一種辦法可以解決,就是重新計算寬度,但這種方法是治標不治本 , 小生不提倡使用這種方法 。
三、設置元素的最小高度和最小寬度
在Web頁面設計中,有時為了達到元素的的統一渲染的風格,我們有時需要使用min-height和min-width來控制元素的最小高度和最小寬度值 。在別的瀏覽器都運行正常,可唯獨這個IE6不識別人家 。因此在使用min-height和min-width時 , 為了達到效果一致,我們要針對IE6另作處理 。其中min-height解決起來相當簡單,但是min-width在IE6下要順利解決就有點麻煩(關于IE6下的min-width放到后面一起探討)這里我們主要來看min-height的解決辦法 。
采用!important方法修復
第一種方法采用的是!important來解決,讓min-height在IE6下能正常工作,具體代碼如下:
復制代碼代碼如下:
.demo {
min-height: 100px;
height: auto !important;/*現代瀏覽器下 , 內容高度超過100px時自動獲得其高度*/
height: 100px;/*此值設置和min-height值一樣,因為IE6下元素高度會根據內容自己的高度而定,所以內容高度低于min-height值時,為了達到min-height效果 , 需要給元素一個顯式的高度值*/
}
采用子選擇器方法來修復
大家都知道IE6是不支持子選擇器的,所以我們也可以使用這個方式來解決min-height在IE6下效果
復制代碼代碼如下:
.demo {
min-height: 100px;
height: 100px;
}
html body .demo {
height: auto;/*只有現代瀏覽器才能識別*/
}
四、塊元素水平居中
元素居中,大家都有碰到過,有時也有不少童鞋會問,怎么我的div元素在IE6下不能居中呢?其實這個Bug并不是什么時候都會發生的,據我查閱相關資料和多次測試,這個Bug只會發生在IE6怪癖模式下,知道問題出在什么地方,那解決起來不難了,最直接的辦法就是在你的頁面頭部記得加上Doctype 。有關于DOCTYPE聲明可以猛點這里查看 。下面我們就針對IE6的怪癖模式來解決這樣的Bug 。
CSS Code
復制代碼代碼如下:
#container{
border: solid 1px #000;
background: #777;
width: 400px;
height: 160px;
margin: 30px 0 0 30px;
}
#element{
background: #95CFEF;
border: solid 1px #36F;
width: 300px;
height: 100px;
margin: 30px auto;
}
產生的效果如圖所示

這主要是由于IE6的quirks模式不識別margin的auto屬性值,但還好,解決這個bug并不復雜 。只需要在居中元素的父元素中加上text-align:center;然后在居中元素中加上text-align:left重新讓元素文本左對齊
復制代碼代碼如下:
#container{
border: solid 1px #000;
background: #777;
width: 400px;
height: 160px;
margin: 30px 0 0 30px;
text-align: center;/*讓子元素在IE6的quirks模式實現水平居中*/
}
#element{
background: #95CFEF;
border: solid 1px #36F;
width: 300px;
height: 100px;
margin: 30px auto;
text-align: left;/*重置文本對齊方式,讓文本左對齊*/
}
當然元素居中問題是一個比較有意思的課題,如果你對這個感興趣也可以閱讀前面我整理的《CSS制作水平垂直居中對齊》一文,這樣你對元素的居中會有更深的了解 。
五、列表li的樓梯Bug
li在IE6下呈樓梯狀的效果,也可以算是IE6的一個經典Bug了吧 。他通常發生在li中放置了一些元素內容(比如說a)而且對其進行浮動,但li本身不浮動,此時在IE下就會有樓梯上了,具體先看下面的代碼:
HTML Markup
復制代碼代碼如下:
ul
lia _fcksavedurl=""#"" /a/li
lia /a/li
lia /a/li
/ul
CSS Code
復制代碼代碼如下:
ul {
list-style: none;
}
ul li a {
display: block;
width: 130px;
height: 30px;
text-align: center;
color: #fff;
float: left;
background: #95CFEF;
border: solid 1px #36F;
margin: 30px 5px;
}
我們一起來看瀏覽器下的效果對比

解決這個Bug也有倆種方法,我們一起來看看
修復方法一:解決這個bug最簡單的方法,只需要在li元素中也加上一個浮動 , 所以你只需這樣做就能解決了
復制代碼代碼如下:
ul li {float: left;}
修復方法二:這個方法二也很簡單 , 就是在li元素上應用display:inline
復制代碼代碼如下:
ul li {display: inline;}
六、li空白間距
這個Bug也是針對于li的,在IE下會無端增中li與li之間的垂直距離 , 別的先不說,先來看下面的代碼
HTML Markup
復制代碼代碼如下:
ul
lia Link 1 /a/li
lia Link 2 /a/li
lia Link 3 /a/li
/ul
CSS Code
復制代碼代碼如下:
ul {
margin:0;
padding:0;
list-style:none;
}
li a {
background: #95CFEF;
display: block;
}
同樣我們來看瀏覽器下的對比圖

雖然在IE6存在這樣的煩人的事情,不過還是值得慶幸的,我們只需在寫代碼時稍加注意,就可以輕松的避免這樣的Bug在你的頁面中出現
方法一:
最簡單的辦法就是給a標簽顯式的定義一個寬度,用聲明寬度的方法來觸發IE瀏覽器的hasLayout , 當然你也可以顯式的定義一個高度,同樣也可以解決,代碼如下:
復制代碼代碼如下:
li a {width: 200px;}
方法二:
方法二是在a標簽上進行浮動,并且清除浮動
復制代碼代碼如下:
li a {
display:block;
float: left;
clear: left;
}
方法三:
方法三也是比較簡單,只在li標簽上加上一個行內元素顯示
復制代碼代碼如下:
li {display: inline;}
li a {display:block;}
方法四:
這種方法是在每個列表li上設置一個底邊實線
復制代碼代碼如下:
ul li { border-bottom: 1px solid #666; }
這種方法問題是解決了 , 但生成了一個新的問題 , 就是li底部有一條實現 , 如果實線顏色和頁面背景色不一致將會給你帶來視覺上的不同,所以最好底線顏色設置成你頁面相同的背景色,當然你也可以嘗試下面的方法來解決:
復制代碼代碼如下:
ul li { border-bottom: 1px solid #ffffff; display:block; margin-bottom: -1px;}
七、IE6下無法設置元素的微高
這個Bug也很有意思 , 有時我們在Web頁面中使用div元素來模擬line或者說制作白色間距,顯顯在元素中定義了好少的高度,比如說2px的height,可是在IE6下,他始終都不以2px的高度見世 , 如下面的一段代碼
復制代碼代碼如下:
.demo {
background: #95CFEF;
border: solid 1px #36F;
width: 300px;
height: 2px;
margin: 30px 0;
}
接著我們來看瀏覽器的對比圖:

造成這要的Bug其實很簡單,因為在IE瀏覽器下,他會拒絕高度小于字號的設置 , 這樣解決起來就很簡單了,我們只需要把元素的字號設置為0,如果為了更安全,你最好加上line-height也為0 , 具體看下面的代碼
復制代碼代碼如下:
.demo {
background: #95CFEF;
border: solid 1px #36F;
width: 300px;
height: 2px;
font-size: 0;
line-height: 0;
margin: 30px 0;
}
上面是通過字體大小來解決,其實還有一種更簡單的方法,利用overflow:hidden將超過高度的部分直接切掉,從而達到2px的微高度設置 , 具體如下
復制代碼代碼如下:
.demo {
background: #95CFEF;
border: solid 1px #36F;
width: 300px;
height: 2px;
margin: 30px 0;
overflow: hidden;
}
八、overflow:auto與position:relative的碰撞
這個Bug也稱作距出邊界的Bug,而這個Bug 只出現在 IE6 和 IE7 中,有兩個塊元素,元素設置了 overflow: auto;子元素設置 position:relative 并且其高度大于父元素,在 IE6 和 IE7 中會產生一個比較難看的 Bug,也就是子元素 塊不被隱藏會溢出父元素塊,而在 IE8 和 FF 還有 IE5.5 中又顯示是正常,我們先來看看這個例子的效 果:
HTML Markup
復制代碼代碼如下:
div id="wrap"
div id="subDiv" /div
/div
CSS Code
復制代碼代碼如下:
#wrap {
border: 1px solid red;
height: 150px;
width: 200px;
background: orange;
overflow: auto;
}
#subDiv {
border: 1px dotted blue;
background: lime;
height: 200px;
width: 150px;
position: relative;
}
瀏覽器中的效果

要解決這個難看的Bug 我們只要在父元素中也設置一個position:relative;屬性,就會使 IE6 和 IE7 回復到正常狀態 。
復制代碼代碼如下:
#wrap {
border: 1px solid red;
height: 150px;
width: 200px;
background: orange;
overflow: auto;
position: relative;
}
這是一個overflow 在IE7~IE6 的bug,不單單只取值auto 會出現這個Bug,就是你設置overflow: hidden 也會出現這個Bug 。解決方法也是只要在父元素中加入一個position: relative;就 OK 了 。
九、浮動層錯位
當內容超出外包容器定義的寬度時會導致浮動層錯位問題 。在 Firefox、IE7、IE8 及其他標準瀏覽 器里,超出的內容僅僅只是超出邊緣;但在 IE6 中容器會忽 視定義的 width 值,寬度會錯誤地隨內 容寬度增長而增長 。如果在這個浮動元素之后還跟著一個 浮動元素,那么就會導致錯位問題
HTML Markup:
復制代碼代碼如下:
div id="container"
div id="left" http://net.tutsplus.com//div
div id="right" /div
/div
CSS Code
復制代碼代碼如下:
#container{
background: #C2DFEF;
border: solid 1px #36F;
width: 365px;
margin: 30px;
padding: 5px;
overflow: auto;
}
#left,
#right{
background: #95CFEF;
border: solid 1px #36F;
width: 100px;
height: 150px;
margin: 30px;
padding: 10px;
float: left;
}
效果圖

解決這樣的bug沒有什么好方法 , 只能在元素中加上overflow:hidden,將多出來的內容直接切掉,如:
復制代碼代碼如下:
#left { overflow: hidden; }
雖然可以使用 overflow:hidden;或 overflow:scroll;來 修正,但 hidden 容易導致其他一些問 題,scroll 會 破壞設計 。最好是使用固定布局或者是使用好寬度
十、IE6下躲貓貓
這個奇怪的 Bug 是 IE6 及其以下版本的,為什么起這樣的一個名稱,因為在某些情況下文本看起 來消失了,重新刷新隱藏的部分才會再度出現 。出現這個 Bug 的條件是:一個撐破了容器浮動元素后 面緊跟著一些非浮動元素,并且非浮動元素中有一些定義了:hover 的鏈接,那么在 IE6 及其以下版中, 當鏈接在懸浮狀態下就會觸發這個奇怪而又無耐的Bug 。
解決這個Bug最好的方法就是清除浮動,因為他是由于浮動才產生的Bug 。有關于清除浮動的方法,大家可以參考《Clear Float 》 。
上面主要搜集了10種Bug,可以說這幾種都是經典的Bug 。希望這幾種能給你今后的工作帶來方便,讓你在Bug還沒出現之前就避免他的發生 。那么第三站我們也要說ByeBye了 , 如果你天天需要面對這個討厭的IE,小生建議你靜下心來細細讀完 。對你會有所幫助的 。如果你有更好的建議,也記得告訴我 。或者在評論中給我留言 。:)
更新一:
在上面的基礎上追加一個典型的IE6 bug: IE6中絕對定位、浮動元素混用時的BUG 。一個內容區塊,其中包含兩個浮動的box,外加一個絕對定位的box,設置如下樣式時會發生IE6浮動元素消失的BUG 。
HTML Code
復制代碼代碼如下:
div class="content"
div class="abs" abs/div
div class="main" main/div
div class="sub" sub/div
/div
CSS Code
復制代碼代碼如下:
*{ padding:0; margin:0;}
.content{width:600px;}
.abs{position:absolute; left:0; top:0; width:600px; height:120px; background:#1f3a87; }
.main{float:left; width:300px; height:200px; background:#f3f3f3; }
.sub{float:left;width:300px; height:200px; background:#bc2931;}
以上代碼在IE6下瀏覽會發現,絕對定位元素不見了 。
解決方法:
給content加一個display:inline樣式可解決 。
各元素的寬度mainsub2content 。給sub加一個margin-right:-3px樣式讓main和sub不要撐滿content可解決 。
在main元素之前加一個空的div/div , 如div/divdiv class=main
給abs元素再嵌套一個div元素,如divdiv class=abs abs/div/div
