IE雙倍邊距BUG 觸發 解決方案
標準參考
根據 W3C CSS2.1 規範中的描述,對於非替換的浮動元素,若 'margin-left' 或 'margin-right' 特性的計算值為 'auto',則它們的實際使用值為 '0'。
除此之外,'margin-left' 與 'margin-right' 特性的計算則採用其自身定義的規範。
關於 'margin-left'、'margin-right' 以及 非替換的浮動元素寬度計算 的詳細資訊,請參考 CSS2.1 規範 8.3 Margin properties: 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', and 'margin' 以及 10.3.5 Floating, non-replaced elements 中的內容。
問題描述
在 IE5.0 IE5.5 IE6 中,當為一個塊級元素同時設定了向左浮動(float:left)及左邊距或右邊距('margin-left' | 'margin-right')後,則該元素的左邊距或右邊距在某些情況下會是設定值的兩倍。同樣地,向右浮動(float:right)及右邊距('margin-right')也存在此現象。
這個是 IE 著名的 "雙邊距Bug"(IE Double Margin Bug)。
造成的影響
這種雙倍邊距的怪異現象會對頁面造成很多影響,如意外折行、溢位、文字重疊等諸多相容性問題。
受影響的瀏覽器
IE5.0 IE5.5 IE6 |
---|
問題分析
首先重現這個 Bug。
分析以下程式碼:
<!DOCTYPE html> <html> <head> <script> window.onload = function () { document.getElementById("d1").innerHTML = document.getElementById("d1").parentNode.offsetWidth; document.getElementById("d2").innerHTML = document.getElementById("d2").parentNode.offsetWidth; } </script> </head> <body style="font:12px Arial; margin:0;"> <div style="width:100px;"> <div style="background:gold; float:left;"> <div id="d1" style="float:left; margin:0 50px; background:olive; width:100px; height:50px;"></div> </div> <div style="background:pink; float:left;"> <div id="d2" style="float:right; margin:0 50px; background:deeppink; width:100px; height:50px;"></div> </div> </div> </body> </html>
上面程式碼中有兩組 DIV 容器,容器內的 DIV 元素分別設定了向左浮動(float:left)與向右浮動(float:right),且左右邊距均為 50px(margin:0 50px)。當頁面載入完畢後將 DIV 容器的 offsetWidth 顯示出來。
在各瀏覽器中開啟這個頁面效果如下:
IE5.0 IE5.5 IE6 | IE7 IE8 Firefox Chrome Safari Opera |
---|---|
從上面的例子與截圖可見:
- 在 IE5.0 IE5.5 IE6 中,當一個塊級元素向左浮動時,其左邊距會出現雙倍於設定的邊距值的現象。當一個塊級元素向右浮動時,其右邊距會出現雙倍於設定的邊距值的現象。由於深黃色的塊級元素為其容器內的最後一個左浮動元素,所以其右邊距也會出現雙倍於設定的右邊距值的現象;
- 在 其他瀏覽器 中,沒有上述的現象,瀏覽器遵照 W3C 規範對頁面元素進行解釋及渲染。
觸發此 Bug 的條件有 3 個:
-
若一個元素向左浮動(float:left),且其設定的左邊距('margin-left')大於其至容器的左側內邊界的距離:
該元素實際的左邊距 = 設定的左邊距 * 2 - 左邊界至容器的距離; -
同樣地,若一個元素向右浮動(float:right),且其設定的右邊距 ('margin-right')大於其至容器的右側內邊界的距離:
該元素實際的右邊距 = 設定的右邊距 * 2 - 右邊界至容器的距離; -
若一個元素向左浮動(float:left),這個元素為其父容器的最後一個左浮動元素,且其設定的右邊距('margin-right')大於其至容器的右側內邊界的距離:
該元素的實際右邊距 = 設定的右邊距 * 2。
下面結合上面的觸發條件看一組更加複雜的例子:
<style> .fl { float:left; height:30px; background:gray; } #A { width:90px; margin:0 10px; } #B { width:85px; margin-left:150px; } #C { width:100px; margin-left:100px; } </style> <div style="width:600px; height:30px; background:#CCC;"> <div id="A" class="fl">10 90 10</div> <div id="B" class="fl">150 85 0</div> <div id="C" class="fl">100 100 0</div> </div>
測試程式碼中 DIV 容器中包含了三個 DIV 子元素,這三個子元素均為左浮動元素,且均擁有 'margin-left' 特性。
不同的瀏覽器執行的結果列表如下:
IE5.0 IE5.5 IE6 |
|
---|---|
IE7 IE8 Firefox Chrome Safari Opera |
在 IE5.0 IE5.5 IE6 中,
- 【A】的左邊距容器的距離為 0,其設定的左邊距為 10px,10 > 0。則【A】滿足上面的條件1,觸發此 Bug。【A】實際的左邊距變為 10 * 2 - 0 = 20px。
- 【B】的左邊距容器的距離為 120px(20 + 90 + 10),其設定的左邊距為 150px,150 > 120。則【B】滿足上面的條件1,觸發此 Bug。【B】實際的左邊距變為150 * 2 - 120 = 180px。
- 【C】的左邊距容器的距離為 385px(20 + 90 + 10 + 180 + 85),其設定的左邊距為 100px,100 < 285。則【C】不滿足觸發此 Bug 的條件。【C】實際的左邊距仍然為 100px。
上面討論的都是元素浮動之前為塊級元素,下面觀察一下 'display' 特性分別為 'inline' 及 'block' 的 SPAN 元素浮動後的情況:
<div style="width:100px; height:20px; background:#ccc;">100 x 20</div> <span style="float:left; margin-left:100px; width:100px; height:20px; background:gray;">inline FLOAT</span> <br /><br /> <div style="width:100px; height:20px; background:#ccc;">100 x 20</div> <span style="float:left; margin-left:100px; width:100px; height:20px; background:gray; display:block">block FLOAT</span>
這段程式碼在不同瀏覽器中執行效果為:
IE5.0 IE5.5 IE6 |
|
---|---|
IE7 IE8 Firefox Chrome Safari Opera |
從上面一組截圖中很明顯的看出,雙邊距 Bug 會作用於 'display' 特性為 'block' 的元素,對於 'inline' 的元素不會觸發此 Bug。
解決方案
- 儘量避免同時使用 'margin-left' 與 float:left,及 'margin-right' 與 float:right;
- 由於這個 Bug 對於 'display' 特性為 'inline' 的元素不會觸發,所以可以通過設定 display:inline 消除此 Bug,由於此 Bug 僅在元素浮動時發生,而浮動將使該元素 'display' 特性計算為 'block' 或者 'table'(見 CSS2.1 規範第 9.7 Relationships between 'display', 'position', and 'float' 節),因此可以通過設定 display:inline 消除雙邊距 Bug。
相關文章
- IE CSS Bug系列:表單控制元件雙邊距BUGCSS控制元件
- 邊距重疊以及解決方案BFC
- css邊距重疊的解決方案CSS
- IE下的圖片空隙間距BUG和解決辦法
- 盒子模型的外邊距塌陷和合並問題及解決方案模型
- jQuery中click事件多次觸發解決方案jQuery事件
- IE CSS Bug系列:邊框在:hover狀態下消失 BugCSS
- 靈感觸發:網路底層安全解決方案
- 雙因素認證解決方案
- 寫出幾種IE6 BUG的解決方法
- Vue 相容 ie9 的全面解決方案VueIE9
- IE CSS Bug系列:IE6中Min-Height的解決辦法CSS
- IMG圖片下面出現下邊距的解決辦法
- HTML中<a>標籤無法使用垂直邊距的解決方法HTML
- Asp.NetEnter鍵觸發Button的OnClick事件解決方案ASP.NET事件
- min-height IE6的解決方案
- jquery中trigger無法觸發hover事件的解決方案jQuery事件
- 白話邊緣計算解決方案 SuperEdge
- 1px邊框解決方案總結
- 行級元素左右邊距及塊級元素上下邊距
- 常見的幾種IE6 BUG及其解決的方法
- Select2外掛 IE下 autofocus bug的解決方法
- 雙碳雙控背景下的智慧環保解決方案
- oralce觸發器解決問題觸發器
- css中內邊距是padding,外邊距是marginCSSpadding
- 關於 Laravel increment 與 decrement 不能觸發觀察者模式的解決方案LaravelREM模式
- 表格的邊距 邊框設定
- CSS 負外邊距CSS
- CSS margin外邊距CSS
- CSS margin 外邊距CSS
- 移動 web 1px 邊框解決方案Web
- IE CSS Bug系列:IE6忽略!important的BugCSSImport
- ie中jQuery無法解析xml檔案的解決方案jQueryXML
- 高併發解決方案詳解(9大常見解決方案)
- Swoole - TCP流資料邊界問題解決方案TCP
- Winform窗體圓角以及描邊完美解決方案ORM
- 【VMware虛擬化解決方案】雙網隔離虛擬化桌面解決方案
- IE9和IE9以下瀏覽器tbody無法使用innerHTML解決方案IE9瀏覽器HTML