IE8+兼容經(jīng)驗(yàn)小結(jié)
2015-07-02 17:43
最近一段時(shí)間,我都使用Flask+Bootstrap3的框架組合進(jìn)行開發(fā)。本文就是在這種技術(shù)組合下,分享IE8+兼容性問題的解決方法。根據(jù)我的實(shí)踐經(jīng)驗(yàn),如果你在寫HTML/CSS時(shí)候是按照W3C推薦的方式寫的,然后下面的幾點(diǎn)都關(guān)注過,那么基本上很大一部分IE8+兼容性問題都OK了(這里的IE8+主要是指IE8,據(jù)個(gè)人目測,IE9+的渲染效果已經(jīng)非常好了)。 前期準(zhǔn)備測試IE兼容性必須要在Windows中測,而且是Win7+,因?yàn)閃inXP最高只支持IE8,IE9就呵呵啦!大部分做Web的童鞋都不是使用Windows做為開發(fā)環(huán)境,要么是Linux發(fā)行版,要么是Mac OS。怎么辦?一般有2種方法: 如果你的機(jī)器足夠快,我推薦前一種方式。但我之前是在二手電腦上開發(fā)的,開虛擬機(jī)簡直卡出翔了,所以采用了第二種方法。如果你是Pythoner,我之前寫的一篇日志《在Windows中搭建Python Web開發(fā)環(huán)境》可能會(huì)對(duì)你有點(diǎn)用處。 然后需要在Win7里安裝用于測試的瀏覽器,查了下百度給出的最近一個(gè)月瀏覽器份額,也不知道準(zhǔn)不準(zhǔn)哈: 我覺得需要測的大概有:IE11、IETester(IE8-IE9)、360瀏覽器、搜狗瀏覽器、Chrome、Firefox、Safari for Windows。IETester測完了建議再用真實(shí)的IE8、IE9測一遍,以防萬一。Safari最好還是找蘋果設(shè)備實(shí)測。 DOCTYPE首先需要確保你的HTML頁面開始部分要有DOCTYPE聲明。DOCTYPE告訴瀏覽器使用什么樣的HTML或XHTML規(guī)范來解析HTML文檔,具體會(huì)影響: DOCTYPE是非常關(guān)鍵的,目前的最佳實(shí)踐就是在HTML文檔的首行鍵入: <!DOCTYPE html> 對(duì)于DOCTYPE的具體闡述就不展開了,可以參考:《正確使用DOCTYPE》、《CS002: DOCTYPE 與瀏覽器模式分析》。 使用meta標(biāo)簽調(diào)節(jié)瀏覽器的渲染方式IE8中有一個(gè)“兼容性視圖”的概念,當(dāng)初IE8發(fā)布時(shí),相對(duì)于IE6/7已經(jīng)做出了非常大的改進(jìn),但是很多老站點(diǎn)僅針對(duì)IE6/7進(jìn)行了優(yōu)化,使用IE8渲染反而會(huì)一團(tuán)糟。為了照顧這些苦逼的前端工程師,IE8加入了“兼容性視圖”功能,這樣的話就可以在IE8中使用IE6或IE7的內(nèi)核渲染頁面。這個(gè)當(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表示如果安裝了針對(duì)IE6/7/8等版本的瀏覽器插件Google Chrome Frame(可以讓用戶的瀏覽器外觀依然是IE的菜單和界面,但用戶在瀏覽網(wǎng)頁時(shí),實(shí)際上使用的是Chrome瀏覽器內(nèi)核),那么就用Chrome內(nèi)核來渲染。關(guān)于此meta標(biāo)簽的具體說明,可參見StackOverflow上的精彩回答。 國內(nèi)存在很多雙核瀏覽器比如360瀏覽器、搜狗瀏覽器,它們是怎么決定某頁面到底使用哪種內(nèi)核渲染?下面引用一段360瀏覽器v6新特性的官方說明: 由于眾所周知的情況,國內(nèi)的主流瀏覽器都是雙核瀏覽器:基于Webkit內(nèi)核用于常用網(wǎng)站的高速瀏覽?;贗E的內(nèi)核用于兼容網(wǎng)銀、舊版網(wǎng)站。以360的幾款瀏覽器為例,我們優(yōu)先通過Webkit內(nèi)核渲染主流的網(wǎng)站,只有小量的網(wǎng)站通過IE內(nèi)核渲染,以保證頁面兼容。在過去很長一段時(shí)間里,我們主要的控制手段是一個(gè)幾百k大小網(wǎng)址庫,一個(gè)通過長期人工運(yùn)營收集的網(wǎng)址庫。 盡管我們努力通過用戶反饋、代碼標(biāo)簽智能判斷技術(shù)提高瀏覽器的自動(dòng)切核準(zhǔn)確率。但是在很多情況下,我們?nèi)匀粺o法達(dá)到百份百正確。因此,我們新增加了一個(gè)控制手段:內(nèi)核控制Meta標(biāo)簽。只要你在自己的網(wǎng)站里增加一個(gè)Meta標(biāo)簽,告訴360瀏覽器這個(gè)網(wǎng)址應(yīng)該用哪個(gè)內(nèi)核渲染,那么360瀏覽器就會(huì)在讀取到這個(gè)標(biāo)簽后,立即切換對(duì)應(yīng)的內(nèi)核。并將這個(gè)行為應(yīng)用于這個(gè)二級(jí)域名下所有網(wǎng)址。
解決方法360已經(jīng)告訴我們了,通過meta標(biāo)簽的方式建議其使用Webkit,代碼如下: <meta name="renderer" content="webkit"> 我沒有做細(xì)致的調(diào)查,不知道其他的雙核瀏覽器是否支持此特性。 Media QueryBootstrap3中使用了大量的Media Query特性,但是IE8似乎無法識(shí)別,所以需要hack一下啦!Bootstrap3的官方文檔中已經(jīng)針對(duì)瀏覽器兼容性做了比較詳細(xì)的說明,推薦采用Respond.js解決此問題,具體方法參見它的文檔即可。 有一個(gè)地方需要注意的是,如果對(duì)Bootstrap3 media query聲明的屬性(比如.container)進(jìn)行覆蓋,那在不支持media query的瀏覽器中Respond.js起作用后,會(huì)把你的覆蓋樣式再次覆蓋。我的解決方案是在后面加上!important。 實(shí)現(xiàn)CSS3的某些特性IE8不支持CSS3的很多新特性,不過我們可以使用一些比較成熟的hack方法,我采用的是CSS3 PIE,它支持的特性有這些:border-radius、box-shadow、border-image、multiple background images、linear-gradient等。 官方文檔給出了2種使用方式,一種是引入.htc文件,另一種則是使用PIE.js。如果使用第一種方法(官方推薦),那么需要設(shè)置.htc文件的Content-Type為text/x-component。這個(gè)也好辦,如果你是通過nginx來托管此文件,只要在Nginx的配置文件中加入一條MIME規(guī)則即可。我建議使用Flask來托管它(放在static文件夾中),這樣更方便,然后只需加入下面的代碼: import mimetypes mimetypes.add_type('text/x-component', '.htc') 特別注意:請(qǐng)一定閱讀CSS PIE給出的Know Issues。 識(shí)別HTML5元素如果你在前端代碼中使用了HTML5的新標(biāo)簽(nav/footer等),那么在IE中這些標(biāo)簽可能無法正常顯示。我使用html5shiv,具體使用方法見文檔。 關(guān)于max-width還有一個(gè)在IE8中經(jīng)常遇到的問題就是max-width,網(wǎng)頁中圖片的尺寸可能比較寬,我會(huì)給它設(shè)置max-width: 100%來限制其寬度最大為父容器的寬度,但是有時(shí)候卻不奏效,慢慢摸索才得知IE解析max-width所遵循的規(guī)則:嚴(yán)格要求直接父元素的寬度是固定的。經(jīng)實(shí)驗(yàn)發(fā)現(xiàn)Chrome所遵守的規(guī)則比IE松一些,所以這個(gè)問題應(yīng)該不歸屬為IE兼容性問題,不過我還是提一下吧。分享兩個(gè)我遇到的場景: (1)td中的max-width 如果針對(duì)td中的img元素設(shè)置max-width: 100%,在IE和Firefox你會(huì)發(fā)現(xiàn)不奏效,而在Chrome中卻是可以的。經(jīng)查詢發(fā)現(xiàn)需要給table設(shè)置,對(duì)此屬性的具體解釋見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è)置了固定寬度,但是對(duì)img設(shè)置max-width為100%卻無效,后來才發(fā)現(xiàn)需要再對(duì)a標(biāo)簽設(shè)置width: 100%,這樣才能使最內(nèi)層的img標(biāo)簽充滿整個(gè)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實(shí)現(xiàn)水平布局。 placeholderIE8下不支持HTML5屬性placeholder,不過為解決此問題的js插件挺多的,比如:jquery-placeholder。 last-childfirst-child是CSS2的內(nèi)容,但是last-child就不是了,所以IE8不買賬。推薦的做法不是使用last-child,而是給最后一個(gè)元素設(shè)置一個(gè).last的class,然后對(duì)此進(jìn)行樣式設(shè)置,這樣就全部兼容了。 background-size: cover如果你想使用background-size: cover設(shè)置全屏背景,很遺憾IE8辦不到...但可以使用IE獨(dú)有的AlphaImageLoader濾鏡來實(shí)現(xiàn),添加一條如下的CSS樣式: filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=Enabled, sizingMethod=Size , src=URL) 將sizingMethod設(shè)置為scale就OK了。 還沒完,如果你在此背景之上放置了鏈接,那這個(gè)鏈接是無法點(diǎn)擊的。一般情況下的解決辦法是為鏈接或按鈕添加position:relative使其相對(duì)浮動(dòng)。 filter blurCSS3中提供支持濾鏡效果的屬性filter,比如支持高斯模糊效果的blur(類似iOS7的效果): filter: blur(10px); -webkit-filter: blur(10px); -moz-filter: blur(10px); IE8對(duì)filter: blur(10px)的顯示效果是對(duì)HTML元素進(jìn)行小范圍的模糊處理,這個(gè)效果并不是高斯模糊,要想支持高斯模糊,需要如下設(shè)置: filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius='10'); 在實(shí)踐中發(fā)現(xiàn)一個(gè)坑就是,所有position: relative的元素都不會(huì)生效。 其他的發(fā)現(xiàn)是,IE9對(duì)filter: blur(10px)無效,而對(duì)filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius='10');是針對(duì)元素小范圍的模糊效果。IE11對(duì)兩種寫法好像都無感。IE10則沒有測試。 好了,目前來說我所遇到的IE8+兼容性問題就這些啦。前端和后端我都做一點(diǎn),這樣的好處在于一個(gè)人能夠獨(dú)立開發(fā)網(wǎng)站,壞處就是各方面都不精。如果你有蠻重要的補(bǔ)充,或者更好的解決方法,歡迎告訴我! PS: 最近做了些IE7兼容方面的工作,相關(guān)的經(jīng)驗(yàn)見IE7+兼容。 |
|