margin系列之bug巡演

2018-02-24 15:22 更新

margin系列之bug巡演

原作者: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/

我所知道的瀏覽器margin bug

  • IE6浮動(dòng)雙倍margin bug;
  • IE6浮動(dòng)相鄰元素3px bug;
  • E6/7 clear引發(fā)的margin-top bug;
  • 待補(bǔ)充的有一堆

為bug生為bug死為bug欲仙欲死的日子

各瀏覽器的實(shí)現(xiàn)差異或者由此而引入的錯(cuò)誤,一直都是前端開(kāi)發(fā)人員的夢(mèng)魘。相信大多數(shù)的前端都為此而精疲力盡過(guò),瀏覽器bug你所知有幾?

IE6浮動(dòng)雙倍margin bug

這當(dāng)是IE6最為經(jīng)典的bug之一。高大上的前端,你肯定從未與其失之交臂過(guò)。

觸發(fā)方式

  • 元素被設(shè)置浮動(dòng)
  • 元素在與浮動(dòng)一致的方向上設(shè)置margin值

來(lái)看看詳細(xì)的代碼吧:

HTML

<div id="demo">
    <p>IE6下浮動(dòng)方向上的margin值將會(huì)雙倍于其指定值</p>
</div>

CSS

#demo p{
    float:left;
    margin-left:10px;
}

效果對(duì)比
非IE6下浮動(dòng)無(wú)雙邊距 (圖一)

圖一 是非IE6下的效果

IE6下浮動(dòng)雙邊距 (圖二)

圖二 是IE6下的效果

從圖一和圖二的對(duì)比,我們?nèi)庋劬涂梢园l(fā)現(xiàn)區(qū)別。是的,IE6下左邊的外邊距變成了 margin-left 指定值的2倍,而其它瀏覽器下正常,這就是經(jīng)典的IE6浮動(dòng)元素雙倍邊距bug。來(lái)看看具體的例子:DEMO1 IE6浮動(dòng)元素雙倍margin bug重現(xiàn)

很開(kāi)心告訴你,問(wèn)題要比這還更復(fù)雜一些,接著往下看。

同個(gè)浮動(dòng)方向的元素只有第一個(gè)元素會(huì)double margin

double margin 并不會(huì)發(fā)生在所有的浮動(dòng)元素上,同個(gè)包含塊內(nèi),在相同的浮動(dòng)方向上,它只發(fā)生在第一個(gè)浮動(dòng)元素上。

用代碼說(shuō)話:

HTML

<div id="demo">
    <p>第一個(gè)float:left</p>
    <p>第二個(gè)float:left</p>
    <p>第三個(gè)float:left</p>
</div>

CSS Code不變,加多2個(gè)浮動(dòng)元素,再來(lái)看具體情況,有圖有真相:

同個(gè)浮動(dòng)方向的元素只有第一個(gè)元素會(huì)double margin (圖三)

看到圖三結(jié)果一目了然,三個(gè) float:left 的元素只有第一個(gè)元素才 double margin 了。用個(gè)例子來(lái)終結(jié)它:DEMO2 同個(gè)浮動(dòng)方向的元素只有第一個(gè)元素會(huì)double margin

double margin只發(fā)生在float:left時(shí)?

你覺(jué)得呢?結(jié)果當(dāng)然不會(huì)是這樣。在之前,我們只說(shuō)過(guò)在同個(gè)浮動(dòng)方向的第一個(gè)浮動(dòng)元素會(huì)double margin,并沒(méi)有說(shuō)只有 float:left 才觸發(fā)。

我們將 DEMO1 的CSS簡(jiǎn)單改改,HTML不變

CSS

#demo p{
    float:right;
    margin-right:10px;
}

結(jié)果會(huì)是怎樣呢?看 圖四

IE6 double margin也會(huì)發(fā)生在float:right時(shí) (圖四)

在圖四中,我們看到右側(cè)的外邊距明顯比指定值 margin-right:10px 要大,恩,確實(shí),它是20px,也double了。瞧瞧:DEMO3 IE6 double margin也會(huì)發(fā)生在float:right時(shí)

既有左浮動(dòng)又有右浮動(dòng)的情況將會(huì)是怎樣呢?

我們先來(lái)將代碼呈上:

HTML

<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>

CSS

#demo .a,#demo .b{
    float:left;
    margin-left:10px;
}
#demo .c,#demo .d{
    float:right;
    margin-right:10px;
}

是的,你可能想到了,第一個(gè)左浮動(dòng)元素和第一個(gè)右浮動(dòng)元素都將會(huì)出現(xiàn) double margin。來(lái)看 圖五:

既有左浮動(dòng)又有右浮動(dòng)的情況 (圖五)

左右都 double margin 了,這看似挺復(fù)雜,其實(shí)為什么會(huì)這樣,前面都講得比較明白了,所以應(yīng)該能理解?本例也奉上:DEMO4 復(fù)雜的double margin

double margin 不僅僅出現(xiàn)在margin-left/right

和大多數(shù)其它 margin 特性一樣,double margin 也受書(shū)寫模式 writing-mode 影響。我們?cè)陂_(kāi)篇所說(shuō)的觸發(fā)條件之一 元素在與浮動(dòng)一致的方向設(shè)置margin值 ,其實(shí)并不完全精確。當(dāng) writing-mode 為縱向時(shí),會(huì)發(fā)生 double margin 的方向也相應(yīng)變成了縱向。
當(dāng)書(shū)寫模式 writing-mode 縱向時(shí),設(shè)置 float:right 時(shí),會(huì)發(fā)生什么?來(lái)看代碼:

HTML

<div id="demo">
    <p>書(shū)寫模式改變雙倍margin bug方向</p>
</div>

CSS

#demo{
    -webkit-writing-mode:vertical-rl;
    writing-mode:tb-rl;
}
#demo p{
    float:right;
    margin:10px 0;
}

CSS Code中,我們同時(shí)設(shè)置了 margin-top/bottom 的值都為 10px。你預(yù)期會(huì) double 的方向是 top or bottom?不太確定?看到 圖六 你就知道了:

書(shū)寫模式改變IE6浮動(dòng)雙倍margin bug方向 (圖六)

圖六清晰的驗(yàn)證了 writing-mode 會(huì)影響 double margin 的方向;并且當(dāng)設(shè)置了float:right 時(shí),只有 margin-bottom 會(huì) double??纯词纠桑?code>DEMO5 書(shū)寫模式改變IE6浮動(dòng)雙倍margin bug方向

float:left 時(shí), double margin 的將會(huì)是 top or bottom?

大家再猜猜,在書(shū)寫模式為縱向時(shí),設(shè)置了 float:left,結(jié)果又將會(huì)如何?
我們只簡(jiǎn)單的將 DEMO5 中的CSS改成 float:left 其余不變,于是得到 圖七 如下:

![書(shū)寫模式改變IE6浮動(dòng)雙倍margin bug方向

你會(huì)驚訝的發(fā)現(xiàn),margin-top/bottom 兩個(gè)方向都出現(xiàn)了 double,這真是一件好神奇的事,事實(shí)勝于雄辯:DEMO6 書(shū)寫模式縱向時(shí)margin-top/bottom都將double

寫到這,關(guān)于IE6浮動(dòng)雙倍margin bug就說(shuō)的差不多了,包括觸發(fā)方式,各種情景下的變化,還有解決方案。哦,解決方案貌似還沒(méi)寫…

fix IE6浮動(dòng)雙倍margin bug

我們以 DEMO1 作為需要fix的case
給IE6在會(huì) double margin 的方向上設(shè)置小一倍的margin值,如下:

CSS

#demo p{
    float:left;
    margin-left:10px;
    _margin-left:5px;
}

恩,IE6的hack,就不再贅述了。不過(guò)這種處理方式有一個(gè)明顯的缺陷,那就是不夠靈活,無(wú)法通用。因?yàn)楫?dāng)標(biāo)準(zhǔn) margin 值改變時(shí),這個(gè)值就得變化。所以不推薦使用這種方式。

display:inline

CSS

#demo p{
    _display:inline;
    float:left;
    margin-left:10px;
}

恩,仍然是only ie6的hack,不過(guò)這個(gè)方案更Cool,它不需要care margin值到底是什么,足夠靈活。看具體的例子吧:DEMO7 修復(fù)IE6浮動(dòng)雙倍margin bug。至于為什么會(huì)有這種解法,我想只能問(wèn)問(wèn)微軟的童鞋了。

完全沒(méi)想到,單一個(gè)雙邊距bug就寫了這么長(zhǎng)的篇幅,本打算一篇文章涵蓋一堆bug,看來(lái)得分篇了。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)