最近又搞了一波網站的兼容,由於要求ie浏覽器還是要兼容到ie8,所以調起來還是各種蛋疼。
現在就post一些做兼容的總結,可能不夠全面,但是可以告訴大家如何避過一些坑。主要測試了chrome,firefox,ie8、9、11,360浏覽器。
一、基本的css兼容:
1、可能很多人喜歡用css hack的形式去兼容ie浏覽器,但是我自己用起來感覺其實不好使 。ie7-就不考慮了,問題在哪呢,就在ie8的甑別上,你怎麼讓樣式只對ie8起作用。上網搜你可能會得到這樣的答案:
.selector { color: #ff0\0;/*ie8*/ color: #f00\9\0;/*ie9+*/ }
但是實際上你一試就嗝屁了,因為ie8他就是識別ie9能識別的,所以根本不能讓獨立的樣式只對ie8起作用。
更好用的是什麼呢,是用ie浏覽器獨有的文檔注釋的方式。像這樣:
<!DOCTYPE html> <!--[if IE 8 ]> <html class="ie8" lang="en"> <![endif]--> <!--[if IE 9 ]> <html class="ie9" lang="en"> <![endif]--> <!--[if (gt IE 9)|!(IE)]><!--> <html lang="en"> <!--<![endif]-->
屢試不爽,關鍵是可以獨立的維護處理兼容ie浏覽器的樣式表,又不會淹沒在一大堆css hack標識中,只需要在獨立對ie8應用樣式規則的地方,copy該條規則,然後在前面加上 .ie8然後就能隨便寫了,對付ie9也一樣。
2、對於360雙核這種找抽浏覽器,據說添加以下頭部meta信息可以使得網頁用webkit內核渲染:
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
IE=edge:保持使用最高級別模式顯示內容;
chrome=1:谷歌的外掛插件Google Chrome Frame(谷歌內嵌浏覽器框架GCF),使用IE浏覽網頁時實際上是使用Chrome浏覽器內核渲染,最低支持IE6,但前提是客戶端已經安裝GCF。
但實際上這個meta標識是ie浏覽器所識別的(詳情:ies-compatibility-features-for-site-developers/),並不是公認的標准,所以用雙核的浏覽器會傲嬌。當然360也會傲嬌,所以有時你會發現360並不能總是(也可能是我本人rp差)以chrome內核渲染你的按現代標准開發的網頁。
那麼試試這個吧,添加:<meta name="renderer" content="webkit">
這個meta標識是360自家實現的(詳情:meta.html),表示強制要求360這造福中國社會萬千網民的浏覽器用chrome的內核渲染網頁。
ok,一行代碼搞定360絕大部分的兼容。
二、ie8的css兼容
現在說說ie8下的css問題:
1、ie8支持:first-child,但不支持:last-child。因為前者是css2.1標准,後者是css3標准。參下:
CSS 2.1 selectors:Basic CSS selectors including: * (universal selector), > (child selector), :first-child, :link, :visited, :active, :hover, :focus, :lang(), + (adjacent sibling selector), [attr], [attr="val"], [attr~="val"], [attr|="bar"], .foo (class selector), #foo (id selector)
2、 為什麼會發現上面的奇怪的東西(怪我css2.1和css3分不清),因為編譯sass文件後發現ie8下的樣式基本全歇菜了。需要注意的是,如果浏覽器 不支持的選擇器和支持的選擇器寫在一起,那麼整條規則就不起作用了。比如你不小心創造了一個偽元素(是真的偽哦).bb:bb-child, .cc{background:#333;}那麼這整條規則就不起作用了,所有浏覽器在此情況下都會歇菜,.cc的樣式就丟失了。
3、 input設置了左右padding,but輸入較多內容時padding還是會消失。這個問題是無解的,ie浏覽器她就是這麼渲染input的,解決方法是在input 外面套一層div,用div設置左右padding,border,width和height,input只需要設置width和weight為100% 即可。另外,正常來講,如果沒有明確設置height的值,那麼設置的line-height值就是height的值,but對於ie8,如果input 設置了 line-height,那麼input必須設置height,否則input的內容顯示有問題,會上下隱藏部分內容,她就是要躲貓貓。
4、 為什麼上面我不用input的偽元素進行設置而要嵌套多一層div呢?因為input,img,iframe等元素不支持偽元素 -_-||。:before 和:after偽元素指定了一個元素文檔樹內容之前和之後的內容。與'content'屬性聯用,指定了插入的內容(也就是你必須顯性設置content 屬性這兩個偽家伙才能在文檔中顯示出來,哪怕設置content屬性為空字符串也行)。作為DOM元素,偽元素都是在容器內進行渲染的, input,img,iframe等元素都不能包含其他元素,也就是不是容器,所以不能通過偽元素插入內容。
5、 table中如果不是嚴格的用於表格,而是用於奇葩的局部布局時(我也想問為什麼用來布局。。),td設置成inline-block可以排成一行,但是 ie8和ie9 下,如果td中的內容很長,即使td設置了寬度,td也會撐開並占用td設置的margin(廢話,td是沒有margin可言的),直到擠占所有的td 寬度之和為tr的寬度。但是td設置成float:left;就能表現成block。這個不清楚為什麼,但是管用。。
6、父元素的左padding會和子元素的左margin重疊。這個是沒有好好實現盒子模型的事情了,包容吧。。
7、sprite圖中的icons之間最好留空白間隔,哪怕間隔1px也好,否則ie8下會出現使用了某一個icon當背景,icon後面跟著的其他icon也順帶顯示了一小部分的bug,所以icons之間還是要適當留白,不要太省。
三、ie11部分css問題
1、 ie11下很多元素表現和其他浏覽器不一致,比如對應用了同一樣式(不設置 高度)的div,其他浏覽器解析的高度是一致的,但是ie11下該div有可能高度偏大,由此導致一些排版上的問題,所以,如果發現元素排版上下偏移的問題,查看此元素或其當代元素是否設置了高度,統一添上高度一切都ok了。
2、抱歉,ie11問題確實不多。
四、結尾附上一個關於css優先級的奇談
首先我們知道:
1、id選擇器優先級權重比class選擇器大一個數量級,class選擇器權重比標簽選擇器大一個數量級;
2、class選擇器和屬性選擇器同優先級;
3、樣式的優先程度需要根據第1條規則計算整體的優先級,按選擇器權重計算各條樣式規則中所有選擇器優先級之和,哪條規則權重大,那條就說了算。如果相同那麼後面的覆蓋前面的。
4、像這種.dog > p開掛,多了特殊符號的,並不會增加優勢,還是和 .dog p優先級一樣。
然後可以拋出一個問題了:
對於下面的文檔結構,分別對 p | .p | div p | .parent | #parent設置color屬性,那麼優先級如何呢?
<div id="parent" class="parent">
<p class="p">p</p>
</div>
結果很有意思:
也就是 .p > div p > p > #parent > .parent
id選擇器居然比p選擇器優先級還低!將p元素和div元素分開看,.p > div p > p 很正常, #parent > .parent也很正常。所以問題關鍵在子級p和父級#parent, 子級的選擇器優先級比父級的選擇器優先級高,或者說繼承的優先級程度比自身的優先級低!
嵌套多一層看看就知道是不是了,分別對#parent | div | p設置color屬性:
<div id="parent" class="parent"> <div class="mid"> <p id="p" class="p">p</p> <div> </div>
結果確實是p > div > #parent:
即使應用兩個選擇器也無濟於事,依然是p >#parent div
但是只要能定位到p元素,那麼父級選擇器的權重就起作用了,一試便知,對#parent p | #p 設置同樣的樣式結果是這樣的:
嗯,確實如此。所以:
5、css樣式優先級還和繼承有關,繼承的優先級不如本身應用的優先級高。
總結完畢,敬禮。
-------------------------------本文地址: http://hovertree.com/