今天的兼容性問題主要發生在“前端三毒”身上,它們分別是:
- IE 6
- IE 7
- IE 8
2.問題一:寬度計算問題
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> #box{ width: 400px; } .left{ width: 200px; background: red; height: 300px; float: left; } .right{ width: 200px; float: right; } .div{ width: 180px; height: 180px; padding: 15px; background: blue; } </style> </head> <body> <div id="box"> <div class="left"></div> <div class="right"> <div class="div"></div> </div> </div> </body> </html>
上面的這段代碼在標准瀏覽器中的顯示情況如下:

而在 IE 低版本瀏覽器中是一個什么樣子呢?

我勒個去,什么情況?
這其實是因為,在 IE 6 下,子級的寬度會撐開父級設置好的寬度。
而解決方法也非常簡單,將 **子級元素的寬度設置為小於等於父級元素的寬度 **就可以了。
除此之外,也推薦大家在盒模型的計算一定要准確,否則在 IE 下回出現問題。
3. 浮動時的兼容性問題(一)
在前端兼容性中,浮動這里也是兼容性的一個重災區,例如下面的示例代碼。
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .box{ width: 400px; } .left{ background: red; float: left; } .right{ background: blue; float: right; } h3{ margin: 0; height: 40px; } </style> </head> <body> <div id="box"> <div class="left"> <h3>左側</h3> </div> <div class="right"> <h3>右側</h3> </div> </div> </body> </html>
在標准瀏覽器中沒有任何問題。

而在低版本瀏覽器中是什么樣子呢?

這又是因為什么呢?
在 IE 6 中,元素浮動中,如果元素需要寬度進行撐開,需要給里面的塊元素都添加浮動才可以。
那么解決方案也非常簡單,我們只需要給他們的內容也進行浮動就可以。

4. 浮動時的兼容性問題(二)
除了上面的問題,我們再來看一個問題。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .left{ width: 100px; height: 100px; background: red; float: left; } .right{ width: 200px; height: 100px; background: blue; margin-left: 100px; } </style> </head> <body> <div id="box"> <div class="left"></div> <div class="right"></div> </div> </body> </html>
標准瀏覽器中:

妥妥的沒任何問題,但是當在 IE 低版本中運行呢?

發現了么?中間多出來了一個間隙(3px)。
這是因為,在 IE 6/7 下,元素要通過浮動排在同一排,就需要給這行元素都加浮動。
所以我們怎么辦?
該怎么實現還是要怎么實現,別想着偷懶。

5.IE 低版本中的最小高度問題
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> div{ height: 2px; background: red; } </style> </head> <body> <div></div> </body> </html>
標准瀏覽器中顯示正常:

而在 IE 6 下,你會發現一個問題。

WTF? 我明明設置的是 2px ,為什么出來這么粗一根?
這其實是因為,在 IE 6 下元素的高度如果小於 19px 的時候,會被當做 19px 處理。
那么我們怎么解決?
其實非常簡單,直接通過 overflow: hidden;
就可以解決。
6. IE 中的邊框
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> div{ width: 100px; height: 100px; border: 1px dotted red; } </style> </head> <body> <div></div> </body> </html>
在標准瀏覽器中:

而 IE 6 下是一個什么樣子呢??

驚了,這是怎么回事?
要知道,在 IE 6 下不支持 1px 的 dotted 邊框樣式。
那假如美工大爺非要用這個樣式呢?
我們其實可以通過背景平鋪去解決,這里就不去演示了,大家肯定都會,對吧。
7. margin 的問題
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .box{ background: red; border: 1px solid red; zoom:1; } .div{ width: 100px; height: 100px; background: blue; margin: 100px; } </style> </head> <body> <div class="box"> <div class="div"></div> </div> </body> </html>
大家都知道,子級的第一個元素的 margin-top 會直接傳遞給父級,對吧。

而我們其實也可以通過 設置一個 border 去解決這個問題。
這時候在上面的 margin 就可以生效了。

但是,問題來了,你猜在 IE 低版本中是什么樣子呢?

原因:在 IE 下,父級有邊框的時候,子級的 margin 會失效。
為什么會出現這種情況呢?
這其實是在 IE 6/7/8 中才存在的一個屬性,hasLayout。
在 IE 下的大部分兼容性問題都是因為 hasLayout 屬性觸發的問題,盡量觸發 hasLayout 可以減少 IE 的問題。
至於觸發 hasLayout 的方法有非常多,但比較常用的就是 zoom: 1;
,有興趣的小伙伴可以自己嘗試一下。
8.IE 中雙邊距的 BUG
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> body{ margin: 0; } .box{ width: 200px; height: 200px; background: red; float: left; margin: 100px; } </style> </head> <body> <div class="box"></div> </body> </html>
上述這段代碼,在標准瀏覽器中,呈現的模樣:

而在低版本瀏覽器中,呈現的樣式則完全不同。

這個也就是 IE 6 下非常著名的 雙倍邊距 BUG。
這個 BUG 的出現原理是,在 IE 6 下,塊元素有浮動並且橫向的時候有 margin 的時候,橫向的 margin 會擴大兩倍。
那知道原因之后,解決起來也就非常簡單了。
既然塊元素會出現這個問題,那我們就將其轉換為內聯元素。
這樣就不會產生這個問題了。

9.margin 的 雙邊距效果
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .box{ border: 10px solid red; float: left; } .box div{ width: 100px; height: 100px; background: red; margin-left: 30px; border: 5px solid #000; float: left; } </style> </head> <body> <div class="box"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> </div> </body> </html>
這段代碼如果放在標准瀏覽器中,顯示的妥妥的沒問題。

但是如果放在低版本瀏覽器中是個什么樣子呢??

你會發現,margin-left 一行中最左側的第一個元素有雙邊距,而如果換成margin-right 的話,margin-right 一行中最右側的第一個元素有雙邊距。
這個問題的解決方案和上面的那個案例相同,我們可以直接將其轉換成 內聯元素,這樣的話,這個問題就可以直接解決了。

10.li 的浮動間隙問題
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> ul{ margin:0; padding: 0; list-style: none; width: 300px; } li{ list-style: none; height: 30px; border: 1px solid #000; } a{ width: 100px; height: 30px; float: left; background: red; } span{ width: 100px; height: 30px; float: right; background: blue; } </style> </head> <body> <ul> <li> <a href="javascript:void(0)"></a> <span></span> </li> <li> <a href="javascript:void(0)"></a> <span></span> </li> <li> <a href="javascript:void(0)"></a> <span></span> </li> </ul> </body> </html>
上面的代碼在標准瀏覽器中是怎么顯示的呢?

和咱們預料的是相同的,對吧。
但是,你們猜猜在 IE 6 和 IE 7 中是怎么顯示的呢??

在 IE 6/7 下,li 本身沒有浮動,li 里面的內容有浮動,li 下會產生一個間隙。
那么這個問題該如何解決呢?
這里給大家推薦兩個解決方案。
- 給 li 也添加浮動
- 給 li 添加 vertical-align
先來看看給 li 添加浮動的做法。

但是注意一個問題,這樣在 IE 下確實能夠解決這個問題,但是相應的,在標准瀏覽器中,中間的白色塊會消失。

所以,我們推薦使用第二種做法,就是去添加 vertical-align。
大家還記得我在之前寫的一篇文章,專門說 img 標簽在下面有一條白色間隙的文章么?
這個問題的解決方案同樣也是需要修改 vertical-align 的 屬性,將默認的 baseline 修改為其他內容。

11. 當最小高度和 li 問題一起發生的時候
基於上面的 li 問題,如果我們同時觸發最小高度和 li 的問題的時候,該怎么辦呢?
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> ul{ margin:0; padding: 0; list-style: none; width: 300px; } li{ list-style: none; height: 12px; border: 1px solid #000; } a{ width: 100px; height: 12px; float: left; background: red; } span{ width: 100px; height: 12px; float: right; background: blue; } </style> </head> <body> <ul> <li> <a href="javascript:void(0)"></a> <span></span> </li> <li> <a href="javascript:void(0)"></a> <span></span> </li> <li> <a href="javascript:void(0)"></a> <span></span> </li> </ul> </body> </html>
標准瀏覽器中的樣式:

而在低版本瀏覽器中呢?

這時候肯定有很多小伙伴開始動腦筋了,既然兩個問題在一起,那我就直接將兩個問題的解決代碼一起加上唄。

這時候,你會發現,最小高度的問題確實解決了,但是間隙還是存在呀?
這時候就是我要給大家提示的一個問題,在 IE 6 下,最小高度的 BUG 和 li 的間隙問題共存的時候,使用 vertical-align 是無效的。
我們必須要使用 float : left;
。
12.前端三毒中最恐怖的一毒
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .box{ border: 10px solid red; } .box div{ width: 100px; height: 100px; background: blue; border: 5px solid #000; margin: 20px; float: left; display: inline; } </style> </head> <body> <div class="box"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> </div> </body> </html>
鑒於這個問題非常“恐怖”,我們一點點的來分析。
首先咱們先來看看,初始狀態現在是什么樣子?
標准瀏覽器:

IE 低版本:

而且,我們發現不僅僅在下方的 margin 失效了,並且發現在前面還存在一個雙邊距的現象。
那我們怎么辦呢?
我們可以去添加一個寬度。

這時候在 IE 瀏覽器下顯示正常了。

但是相對的,在標准瀏覽器中會失效。

這時候怎么辦呢?
我們可以去添加一個 overflow。

這時候,顯示確實正常了。
注意:前方高能!!!
當我們將寬度一像素,一像素的增加的時候。

當你增加到 3px 的時候(作者這里增加到 5px 才觸發這個現象,應該是模擬器不准確),會突然發現,底部的 margin 又失效了。

而且還存在另外一個非常詭異的現象。
我們首先將剛才的代碼做一下修改。

這時候顯示是正常的。

但是當我們注釋某一個 div 的時候(刪除也可以),剛才的現象又發生了。
(作者這里注釋了兩個,為大家演示一下,注釋一個也是相同的。)

實際上,這其實是因為當一行子級元素寬度之和和父級的寬度相差超過 3px,或者 子級元素不滿行的情況時,最后一行的子級元素的 margin-bottom 會失效。
這個問題沒法解決,只能夠避免。
這點一定要注意。
13.文字溢出 BUG
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .box{ width: 400px; } .left{ float: left; } .right{ float: right; width: 400px; } </style> </head> <body> <div class="box"> <div class="left"></div> <span></span> <div class="right">李先生真帥</div> </div> </body> </html>
這個 BUG 是怎么回事呢?
運行上面的代碼,在正常瀏覽器內顯示沒有任何問題。

但是需要注意,如果在 IE 6里面,你會發現一個奇怪的現象。

我們下面怎么多了一個“帥”字呀?
如果你在下面多加一個 span
標簽呢?
兩個 span:

三個 span:

四個 span:

我們會發現,甚至於我們的第一行文字直接全部消失了。
這個就是 IE 6 下的文字溢出 BUG.
子元素的寬度和父級的寬度如果相差小於 3px 的時候,兩個浮動元素中間有注釋或者內聯元素的時候,就會出現文字溢出,內聯元素越多,溢出越多.
而且,如果中間存在注釋,也會觸發 BUG.

既然我們將問題提了出來,那就肯定有解決的辦法。
我們推薦,用 塊元素標簽 把注釋或者內聯元素包裹起來。
這樣就可以有效的避免觸發這個 BUG 了。
14.絕對定位失效 BUG
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .box{ width: 200px; height: 200px; border: 1px solid #000; position: relative; } a{ position: absolute; width: 40px; height: 40px; background: red; right: 20px; top: 20px; } ul{ width: 150px; height: 150px; background: yellow; margin: 0 0 0 50px; padding: 0; float: left; display: inline; } </style> </head> <body> <div class="box"> <ul></ul> <a href="javascript:void(0)"></a> </div> </body> </html>
上面的案例代碼,在標准瀏覽器中顯示完全沒有問題。

但是當我們在低版本瀏覽器中,顯示就會出現問題了。

這個問題的觸發原因:
在 IE 6 下,當浮動元素和絕對定位元素是兄弟關系的時候,絕對定位會失效。
那我們該怎么解決呢?
非常簡單,不讓浮動元素和絕對定位是兄弟關系就可以咯。
我們可以用 div 標簽嵌套一下,這樣分隔開來就不會觸發剛才的問題了。
15.滑動元素 BUG
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .box{ width: 200px; height: 200px; border: 1px solid #000; overflow: auto; } .div{ width: 150px; height: 300px; background: red; position: relative; } </style> </head> <body> <div class="box"> <div class="div"></div> </div> </body> </html>
這時候我們在標准瀏覽器中查看一下。

不管是滑動還是其他方式都沒問題,但是,IE 下就沒問題了么?

哼哼,前端三毒,名不虛傳。
問題原因在這:在 IE 6/7 下,子級元素有相對定位,父級 overflow 包不住子級元素。
那我們該怎么處理這個問題?
既然子元素有相對定位,那我們就給父元素同樣給出相對定位唄。

這樣就能輕松解決掉這個問題了。
16.像素偏差 BUG
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .box{ width: 201px; height: 201px; border: 1px solid #000; position: relative; } .box span{ width: 20px; height: 20px; background: yellow; position: absolute; right: -1px; bottom: -1px; } </style> </head> <body> <div class="box"> <span></span> </div> </body> </html>
上面的代碼,在 標准瀏覽器中可以正常顯示。

但是如果放在 IE 中顯示呢?

這個問題的原因:
在 IE 6 下,如果絕對定位的父級寬和高是奇數的時候,子級元素的 right 和 bottom 會有1像素的偏差。
至於解決方案,不好意思,沒有。

這個東西只能去盡量避免,如果沒辦法,只能這么做,那你就要和美工大爺提前商量好了,要么你改,要我我弄完你別找我的事。(我以前就這么干的,羞澀...)
17.固定定位 BUG
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> body{ height: 2000px; background: red; } .box{ width: 200px; height: 200px; background: yellow; position: fixed; top: 30px; left: 100px; } </style> </head> <body> <div class="box"></div> </body> </html>
我們在標准瀏覽器中,顯示是正常的。

而在 IE 瀏覽器中,你會發現,咱們設置的 固定定位失效了!

這其實是因為,在 IE 6 中不存在固定定位,只存在絕對定位。
那我們該怎么做呢?
在 IE 低版本下,我們只能通過 JS 去模擬這個效果。
18.透明度失效
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> body{ height: 2000px; background: red; } .box{ width: 200px; height: 200px; background: yellow; position: fixed; top: 30px; left: 100px; opacity: 0.5; } </style> </head> <body> <div class="box"></div> </body> </html>
我們在應用了定位之后,經常會用到 opacity
這個屬性,在標准瀏覽器中,顯示是沒有任何問題的。

但是如果在 IE 中去查看呢?
你會發現,我的透明度失效了!

這其實是因為,在 IE 中其實是不認識 opacity 這個屬性的。
那我們如果想要在 IE 中使用透明度,該怎么做呢?
我們可以這么用。

這樣我們的透明度就都可以正常使用了。
19.input 元素的 BUG
案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .box{ width: 200px; height: 32px; border: 1px solid #000; } input{ width: 100px; height: 30px; border: 1px solid red; margin: 0; padding: 0; } </style> </head> <body> <div class="box"> <input type="text" name=""> </div> </body> </html>
在標准瀏覽器中顯示是沒有什么異常的。

但是,在 IE 6 和 IE 7 中,輸入型表單控件上下會有 1px 的間隙。

那我們怎么去解決呢?
我們其實可以通過設置浮動就能解決。

20. IE 中不支持 png 圖片的問題
我們在平時的開發中,難免會遇到各種各樣的圖片,很多時候都是我們的美工大爺給我們提前切好的,但是我們偶爾還是需要自己弄一些圖片。
那在處理圖片之后,大家一般使用的圖片格式都是什么呢?
他們之間有哪些區別呢?我們今天首先來看一下。
這里我首先通過 PS 去制作了一張圖片,具體的圖片制作方式在此不做更多說明。
重點在圖片的導出的時候,我們在導出時,不同的圖片格式都有什么差別呢?
首先我們先來看看 GIF 的導出。

我們會發現,圖片要么是直接透明的,要么是不透明的,不存在漸變這個效果。
而 JPEG 呢?

完全沒有透明效果。
而 我們常用的 PNG 格式呢?
這里首先來看看 PNG-8

和 GIF 非常類似,但是大小要小很多。
最后我們再來看看 PNG-24.

我們會發現,我們圖片的大小略大,但是透明效果全部存在。
明白了上面各種圖片的特性之后,我們再來看看下面的案例。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> body{ background: #000; } .box{ width: 400px; height: 400px; background: url("1.png"); } </style> </head> <body> <div class="box"></div> </body> </html>
在標准瀏覽器中,顯示完全沒有問題。

那么接下來一起再來看看 IE 中的顯示。

發現了么?
我們的透明效果完全失效了,我們使用的可是 PNG-24 呀。
這是為什么呢?
這其實是因為,在IE 6 下,不支持透明度的方式。
那我們怎么去處理這個問題呢?
我們其實可以通過一個 JS 文件來處理它。
處理工具:DD_belatedPNG
使用起來其實也非常簡單。

這樣在 IE 6下,我們的 PNG 圖片也可以正常顯示啦。
21.條件注釋語句
接下來給大家介紹一個小套路,就是條件注釋語句,這個是我們平常處理兼容時很常用的一個小技巧。
使用方式也非常簡單。

注意,這里的書寫方式是固定的,不能夠更改。
那我們寫這個有什么效果呢?
我們會發現,在標准瀏覽器中我們是看不見任何東西的。

但是在特定的 IE 版本中,我們可以看到注釋之間的文字。

甚至我們也可以在蘋果官網中看到這樣的處理方法。

22.CSS HACK
最后再給大家介紹一個差不多算是“走火入魔”的處理方法。
就是我們其實可以根據不同的 IE 瀏覽器版本去執行特定的代碼。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> /* CSS HACK */ .box{ width: 100px; height: 100px; background: red; background: yellow\9; +background: black; _background:pink; /* \9 : IE 10 之前的瀏覽器解析的代碼 + 或者 * : IE 7(包括 7)之前的 IE 瀏覽器 _ : IE 6(包括 6)之前的 IE 瀏覽器 */ } </style> </head> <body> <div class="box"></div> </body> </html>
我們可以看到,如果我當前的版本是 IE 7,我可以在 background 前面跟上一個 “+”。
這樣在 IE 7 以及之前的版本里,就能識別對應的這段代碼了。

IE 7 瀏覽器:

網址:https://www.jianshu.com/p/25ffda51e9a8