原作者:doyoe
原文鏈接:http://blog.doyoe.com/2013/12/10/css/margin%E7%B3%BB%E5%88%97%E4%B9%8Bbug%E5%B7%A1%E6%BC%94/
各瀏覽器的實現(xiàn)差異或者由此而引入的錯誤,一直都是前端開發(fā)人員的夢魘。相信大多數(shù)的前端都為此而精疲力盡過,瀏覽器bug你所知有幾?
這當(dāng)是IE6最為經(jīng)典的bug之一。高大上的前端,你肯定從未與其失之交臂過。
來看看詳細(xì)的代碼吧:
<div id="demo">
<p>IE6下浮動方向上的margin值將會雙倍于其指定值</p>
</div>
#demo p{
float:left;
margin-left:10px;
}
效果對比
(圖一)
圖一 是非IE6下的效果
(圖二)
圖二 是IE6下的效果
從圖一和圖二的對比,我們?nèi)庋劬涂梢园l(fā)現(xiàn)區(qū)別。是的,IE6下左邊的外邊距變成了 margin-left
指定值的2倍,而其它瀏覽器下正常,這就是經(jīng)典的IE6浮動元素雙倍邊距bug。來看看具體的例子:DEMO1
IE6浮動元素雙倍margin bug重現(xiàn)
很開心告訴你,問題要比這還更復(fù)雜一些,接著往下看。
double margin
并不會發(fā)生在所有的浮動元素上,同個包含塊內(nèi),在相同的浮動方向上,它只發(fā)生在第一個浮動元素上。
用代碼說話:
<div id="demo">
<p>第一個float:left</p>
<p>第二個float:left</p>
<p>第三個float:left</p>
</div>
CSS Code不變,加多2個浮動元素,再來看具體情況,有圖有真相:
(圖三)
看到圖三結(jié)果一目了然,三個 float:left
的元素只有第一個元素才 double margin
了。用個例子來終結(jié)它:DEMO2
同個浮動方向的元素只有第一個元素會double margin
你覺得呢?結(jié)果當(dāng)然不會是這樣。在之前,我們只說過在同個浮動方向的第一個浮動元素會double margin,并沒有說只有 float:left
才觸發(fā)。
我們將 DEMO1
的CSS簡單改改,HTML不變
#demo p{
float:right;
margin-right:10px;
}
結(jié)果會是怎樣呢?看 圖四
:
(圖四)
在圖四中,我們看到右側(cè)的外邊距明顯比指定值 margin-right:10px
要大,恩,確實,它是20px,也double了。瞧瞧:DEMO3
IE6 double margin也會發(fā)生在float:right時
我們先來將代碼呈上:
<div id="demo">
<p class="a">1 float:left</p>
<p class="b">2 float:left</p>
<p class="c">3 float:right</p>
<p class="d">4 float:right</p>
</div>
#demo .a,#demo .b{
float:left;
margin-left:10px;
}
#demo .c,#demo .d{
float:right;
margin-right:10px;
}
是的,你可能想到了,第一個左浮動元素和第一個右浮動元素都將會出現(xiàn) double margin
。來看 圖五:
(圖五)
左右都 double margin
了,這看似挺復(fù)雜,其實為什么會這樣,前面都講得比較明白了,所以應(yīng)該能理解?本例也奉上:DEMO4
復(fù)雜的double margin
和大多數(shù)其它 margin
特性一樣,double margin
也受書寫模式 writing-mode
影響。我們在開篇所說的觸發(fā)條件之一 元素在與浮動一致的方向設(shè)置margin值 ,其實并不完全精確。當(dāng) writing-mode
為縱向時,會發(fā)生 double margin
的方向也相應(yīng)變成了縱向。
當(dāng)書寫模式 writing-mode
縱向時,設(shè)置 float:right
時,會發(fā)生什么?來看代碼:
<div id="demo">
<p>書寫模式改變雙倍margin bug方向</p>
</div>
#demo{
-webkit-writing-mode:vertical-rl;
writing-mode:tb-rl;
}
#demo p{
float:right;
margin:10px 0;
}
CSS Code中,我們同時設(shè)置了 margin-top/bottom
的值都為 10px。你預(yù)期會 double
的方向是 top or bottom
?不太確定?看到 圖六
你就知道了:
(圖六)
圖六清晰的驗證了 writing-mode
會影響 double margin
的方向;并且當(dāng)設(shè)置了float:right
時,只有 margin-bottom
會 double
??纯词纠桑?code>DEMO5 書寫模式改變IE6浮動雙倍margin bug方向
大家再猜猜,在書寫模式為縱向時,設(shè)置了 float:left,結(jié)果又將會如何?
我們只簡單的將 DEMO5
中的CSS改成 float:left
其余不變,于是得到 圖七
如下:
![
你會驚訝的發(fā)現(xiàn),margin-top/botto
m 兩個方向都出現(xiàn)了 double,這真是一件好神奇的事,事實勝于雄辯:DEMO6
書寫模式縱向時margin-top/bottom都將double
寫到這,關(guān)于IE6浮動雙倍margin bug就說的差不多了,包括觸發(fā)方式,各種情景下的變化,還有解決方案。哦,解決方案貌似還沒寫…
我們以 DEMO1
作為需要fix的case
給IE6在會 double margin
的方向上設(shè)置小一倍的margin值,如下:
#demo p{
float:left;
margin-left:10px;
_margin-left:5px;
}
恩,IE6的hack,就不再贅述了。不過這種處理方式有一個明顯的缺陷,那就是不夠靈活,無法通用。因為當(dāng)標(biāo)準(zhǔn) margin
值改變時,這個值就得變化。所以不推薦使用這種方式。
#demo p{
_display:inline;
float:left;
margin-left:10px;
}
恩,仍然是only ie6的hack,不過這個方案更Cool,它不需要care margin值到底是什么,足夠靈活??淳唧w的例子吧:DEMO7
修復(fù)IE6浮動雙倍margin bug。至于為什么會有這種解法,我想只能問問微軟的童鞋了。
完全沒想到,單一個雙邊距bug就寫了這么長的篇幅,本打算一篇文章涵蓋一堆bug,看來得分篇了。
更多建議: