本文摘抄自:http://www.hustlzp.com/post/2014/01/ie8-compatibility
前期準(zhǔn)備
測試IE兼容性必須要在 Windows 中測,而且是 Win7+,因為 WinXP最高只支持 IE8,IE9就呵呵啦。
大部分做 Web 的童鞋都不是使用 Windows 作為開發(fā)環(huán)境,要么是 Linux 發(fā)行版,要么是 Mac OS,這個時候可以有兩種方法解決:
- 開 Windows 虛擬機(jī)
- 將開發(fā)環(huán)境暫時切換到 Windows
DOCTYPE
首先需要確保你的 HTML 頁面開始部分要有 DOCTYPE 聲明。DOCTYPE 告訴瀏覽器使用什么樣的 HTML 或 XHTML 規(guī)范來解析 HTML 文檔,具體會影響:
- 對標(biāo)記、attributes、properties 的約束規(guī)則
- 對瀏覽器的渲染模式產(chǎn)生影響,不同的渲染模式會影響到瀏覽器對于 CSS 代碼甚至 JavaScript 腳本的解析
DOCTYPE 是非常關(guān)鍵的,目前的最佳實踐就是在 HTML 文檔的首行鍵入:
<!DOCTYPE html>
對于 DOCTYPE 的具體闡述就不展開了,可以參考: 《正確使用DOCTYPE》、《CS002: DOCTYPE 與瀏覽器模式分析》。
使用 meta 標(biāo)簽調(diào)節(jié)瀏覽器的渲染方式
IE8 中有一個"兼容性視圖"的概念,當(dāng)初 IE8 發(fā)布時,相對于 IE6/7 已經(jīng)做出了非常大的改進(jìn),但是很多老站點僅針對 IE6/7 進(jìn)行了優(yōu)化,使用 IE8 渲染反而會一團(tuán)糟。為了照顧這些苦逼的前端工程師,IE8 加入了 "兼容性視圖"功能,這樣的話就可以在 IE8 中使用 IE6 和 IE7 的內(nèi)核渲染頁面。這個當(dāng)然不是我們想要的,所以需要使用 meta 標(biāo)簽來強(qiáng)制 IE8 使用最新的內(nèi)核渲染頁面,代碼如下:
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
IE=edge 表示強(qiáng)制使用 IE 最新內(nèi)核, chrome=1 表示如果安裝了針對 IE6/7/8 等版本的瀏覽器插件 Google Chrome Frame (可以讓用戶的瀏覽器外觀依然是 IE 的菜單和界面,但用戶在瀏覽網(wǎng)頁時,實際上使用的是 Chrome 瀏覽器內(nèi)核),那么就用 Chrome 內(nèi)核來渲染。
由于眾所周知的情況,國內(nèi)的主流瀏覽器都是雙核瀏覽器:基于Webkit內(nèi)核用于常用網(wǎng)站的高速瀏覽。基于IE的內(nèi)核用于兼容網(wǎng)銀、舊版網(wǎng)站。以360的幾款瀏覽器為例,我們優(yōu)先通過Webkit內(nèi)核渲染主流的網(wǎng)站,只有小量的網(wǎng)站通過IE內(nèi)核渲染,以保證頁面兼容。在過去很長一段時間里,我們主要的控制手段是一個幾百k大小網(wǎng)址庫,一個通過長期人工運營收集的網(wǎng)址庫。
盡管我們努力通過用戶反饋、代碼標(biāo)簽智能判斷技術(shù)提高瀏覽器的自動切核準(zhǔn)確率。但是在很多情況下,我們?nèi)匀粺o法達(dá)到百份百正確。因此,我們新增加了一個控制手段:內(nèi)核控制Meta標(biāo)簽。只要你在自己的網(wǎng)站里增加一個Meta標(biāo)簽,告訴360瀏覽器這個網(wǎng)址應(yīng)該用哪個內(nèi)核渲染,那么360瀏覽器就會在讀取到這個標(biāo)簽后,立即切換對應(yīng)的內(nèi)核。并將這個行為應(yīng)用于這個二級域名下所有網(wǎng)址。
解決方法360已經(jīng)告訴我們了,通過meta標(biāo)簽的方式建議其使用Webkit,代碼如下:
<meta name="renderer" content="webkit">
我沒有做細(xì)致的調(diào)查,不知道其他的雙核瀏覽器是否支持此特性。
Media Query
IE8 似乎無法識別 Media Query,所以需要 hack 一下啦!推薦采用 Respond.js 解決此問題,具體方法參見它的文檔即可。
實現(xiàn)CSS3的某些特性
IE8 不支持 CSS3 的很多新特性,不過我們可以使用一些比較成熟的 hack 方法,我采用的是 CSS3 PIE,它支持的特性有這些:border-radius、box-shadow、border-image、multiple background images、linear-gradient等。
特別注意:請一定閱讀 CSS PIE 給出的 Know Issues。
識別HTML5元素
如果你在前端代碼中使用了 HTML5 的新標(biāo)簽(nav/footer等),那么在IE中這些標(biāo)簽可能無法正常顯示。我使用 html5shiv,具體使用方法見文檔。
關(guān)于max-width
還有一個在IE8中經(jīng)常遇到的問題就是 max-width,網(wǎng)頁中圖片的尺寸可能比較寬,我會給它設(shè)置 max-width: 100% 來限制其寬度最大為父容器的寬度,但是有時候卻不奏效,慢慢摸索才得知 IE 解析 max-width 所遵循的規(guī)則:嚴(yán)格要求直接父元素的寬度是固定的。經(jīng)實驗發(fā)現(xiàn) Chrome 所遵守的規(guī)則比 IE 松一些,所以這個問題應(yīng)該不歸屬為 IE 兼容性問題,不過我還是提一下吧。分享兩個我遇到的場景:
(1)td 中的 max-width
如果針對 td 中的 img 元素設(shè)置 max-width: 100%,在 IE 和 Firefox 你會發(fā)現(xiàn)不奏效,而在 Chrome 中卻是可以的。經(jīng)查詢發(fā)現(xiàn)需要給 table 設(shè)置 table-layout: fixed,對此屬性的具體解釋見 W3School。
(2)嵌套標(biāo)簽中的 max-width
如下的HTML結(jié)構(gòu):
<div class="work-item">
<a href="#" class="work-link">
<img src="sample.jpg" class="work-image img-responsive">
</a>
</div>
最外層元素 .work-item 設(shè)置了固定寬度,但是對 img 設(shè)置 max-width 為 100% 卻無效,后來才發(fā)現(xiàn)需要再對 a 標(biāo)簽設(shè)置 width: 100%,這樣才能使最內(nèi)層的 img 標(biāo)簽充滿整個 div。
嵌套 inline-block 下 padding 元素重疊
HTML代碼:
<ul>
<li><a>1</a></li>
<li><a>2</a></li>
<li><a>3</a></li>
</ul>
CSS代碼:
ul li {
display: inline-block;
}
ul li a {
display: inline-block;
padding: 10px 15px;
}
按理來說 a 標(biāo)簽之間的距離應(yīng)該是 30px,但在 IE8 中出現(xiàn)了重疊,只有 15px。這里和這里也提到了同樣的問題。我的解決方法是使用 float: left 替代 display: inline-block 實現(xiàn)水平布局。
placeholder
IE8 下不支持 HTML5 屬性 placeholder,不過為解決此問題的 js 插件挺多的,比如:jquery-placeholder
last-child
first-child 是 CSS2 的內(nèi)容,但是 last-child 就不是了,所以 IE8 不買賬。推薦的做法不是使用 last-child,而是給最后一個元素設(shè)置一個 .last 的 class ,然后對此進(jìn)行樣式設(shè)置,這樣就全部兼容了。
background-size: cover
如果你想使用 background-size: cover 設(shè)置全屏背景,很遺憾 IE8 辦不到...但可以使用 IE 獨有的 AlphaImageLoader 濾鏡來實現(xiàn),添加一條如下的 CSS 樣式:
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=Enabled, sizingMethod=Size , src=URL)
將 sizingMethod 設(shè)置為 scale 就OK了。
還沒完,如果你在此背景之上放置了鏈接,那這個鏈接是無法點擊的。一般情況下的解決辦法是為鏈接或按鈕添加 position:relative 使其相對浮動。
filter blur
CSS3 中提供支持濾鏡效果的屬性 filter,比如支持高斯模糊效果的 blur(類似iOS7的效果):
filter: blur(10px);
-webkit-filter: blur(10px);
-moz-filter: blur(10px);
IE8 對 filter: blur(10px) 的顯示效果是對 HTML 元素進(jìn)行小范圍的模糊處理,這個效果并不是高斯模糊,要想支持高斯模糊,需要如下設(shè)置:
filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius='10');
在實踐中發(fā)現(xiàn)一個坑就是,所有 position: relative 的元素都不會生效。
其他的發(fā)現(xiàn)是,IE9 對 filter: blur(10px) 無效,而對 filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius='10'); 是針對元素小范圍的模糊效果。
好了,目前來說我所遇到的IE8+兼容性問題就這些啦。前端和后端我都做一點,這樣的好處在于一個人能夠獨立開發(fā)網(wǎng)站,壞處就是各方面都不精。如果你有蠻重要的補充,或者更好的解決方法,歡迎告訴我!