寫css樣式的時候,恐怕最頭疼的就是各個瀏覽器下的兼容性問題,即css hack,不同的瀏覽器對css的解析結果是不同的,因此會導致相同的css輸出的頁面效果不同,這就需要css hack來解決瀏覽器局部的兼容性問題。使用css、 hack將會使用你的css代碼部分失去作用,然后借助條件樣式,使用其原css代碼在一些瀏覽器解析,而css hack代碼在符合條件要求的瀏覽器中替代原css那部分代碼。
css hack基本概念
CSS hack是通過在CSS樣式中加入一些特殊的符號,讓不同的瀏覽器識別不同的符號(什么樣的瀏覽器識別什么樣的符號是有標準的,CSS hack就是讓你記住這個標準),以達到應用不同的CSS樣式的目的,比如.kwstu{width:300px;_width:200px;},一般瀏覽器會先給元素使用width:300px;的樣式,緊接著后面還有個_width:200px;由于下劃線_width只有IE6可以識別,所以此樣式在IE6中實際設置對象的寬度為200px,后面的把前面的給覆蓋了,而其他瀏覽器不識別_width不會執行_width:200px;這句樣式,所以在其他瀏覽器中設置對象的寬度就是300px;
簡單地講,css hack指各版本及各品牌瀏覽器之間對CSS解釋后出現網頁內容的誤差(比如我們常說錯位)的處理。由于各瀏覽器的內核不同,所以會造成一些誤差就像JS一樣,一個JS網頁特效,在微軟IE6、IE7、IE8瀏覽器有效果,但可能在火狐(Mozilla Firefox)谷歌瀏覽器無效,這樣就叫做JS hack ,所以我們對于CSS來說他們來解決各瀏覽器對CSS解釋不同所采取的區別不同瀏覽器制作不同的CSS樣式的設置來解決這些問題就叫作CSS Hack。
CSS Hack常見的有三種形式:CSS屬性Hack、CSS選擇符Hack以及IE條件注釋Hack, Hack主要針對IE瀏覽器。
1、屬性級Hack:比如IE6能識別下劃線”_”和星號” * “,IE7能識別星號” * “,但不能識別下劃線”_”,而firefox兩個都不能認識。
2、選擇符級Hack:比如IE6能識別*html .class{},IE7能識別*+html .class{}或者*:first-child+html .class{}。
3、IE條件注釋Hack:IE條件注釋是微軟從IE5開始就提供的一種非標準邏輯語句。比如針對所有IE:<!–[if IE]><!–您的代碼–><![endif]–>,針對IE6及以下版本:<!–[if lt IE 7]><!–您的代碼–><![endif]–>,這類Hack不僅對CSS生效,對寫在判斷語句里面的所有代碼都 會生效。
PS:條件注釋只有在IE瀏覽器下才能執行,這個代碼在非IE瀏覽下被當做注釋視而不見。可以通過IE條件注釋載入不同的CSS、JS、HTML和服務器代碼等。
各瀏覽器下Hack的寫法
1、Firefox
@-moz-document url-prefix() { .selector { property: value; } }
上面是僅僅被Firefox瀏覽器識別的寫法,具體如:
@-moz-document url-prefix() { .demo { color:lime; } }
支持Firefox的還有幾種寫法:
/* 支持所有firefox版本 */ #selector[id=selector] { property: value; } 或者: @-moz-document url-prefix() { .selector { property: value; } } /* 支持所有Gecko內核的瀏覽器 (包括Firefox) */ *>.selector { property: value; }
2、Webkit枘核瀏覽器(chrome and safari)
@media screen and (-webkit-min-device-pixel-ratio:0) { Selector { property: value; } }
上面寫法主要是針對Webkit內核的瀏覽器,如Google Chrome 和 Safari瀏覽器:
@media screen and (-webkit-min-device-pixel-ratio:0) { .demo { color: #f36; } }
3、Opera瀏覽器
html:first-child>body Selector {property:value;} 或者: @media all and (min-width:0) { Selector {property: value;} } 或者: @media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0) { head~body Selector { property: value; } }
上面則是Opera瀏覽器的Hack寫法:
@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0) { head~body .demo { background: green; } }
4、IE9瀏覽器
:root Selector {property: value9;}
上面是IE9的寫法,具體應用如下:
:root .demo {color: #ff09;}
5、IE9以及IE9以下版本
Selector {property:value9;}
這種寫法只有IE9以及IE9以下版本能識別,這里需要注意此處“9”只能是“9”不能是別的,比如說“8”,不然會失去效果的,如:
.demo {background: lime9;}
Selector {property: value;} }
7、IE8以及IE8以上的版本
Selector {property: value\0;}
這種寫法只有IE8以及IE8以上版本支持,如
.demo {color: #ff0;}
8、IE7瀏覽器
*+html Selector{property:value;} 或 *:first-child+html Selector {property:value;}
上面兩種是IE7瀏覽器下才能識別,如:
*+html .demo {background: green;} 或者: *:first-child+html .demo {background: green;}
9、IE7及IE7以下版本瀏覽器
Selector {*property: value;}
上面的寫法在IE7以及其以下版本都可以識別,如:
.demo {*background: red;}
10、IE6瀏覽器
Selector {_property/**/:/**/value;} 或者: Selector {_property: value;} 或者: *html Selector {property: value;}
具體應用如下:
.demo {_width/**/:/**/100px;} 或者: .demo {_width: 100px;} 或者: *html .demo {width: 100px;}
上面具體介紹了各種版本瀏覽器下如何識別各種的Hack寫法,包括了IE6-9以及現代版本的瀏覽器寫法。綜合上面的所述,我們針對不同瀏覽器的Hack寫法主要分為兩種從CSS選擇器和CSS屬性上來區別不同的Hack寫法。
慎用\0的CSS Hack
在Web頁面制作中盡量不要使用CSS Hack來處理兼容問題。因為任何瀏覽器下出現渲染不一致都極有可能是我們自己的結構或樣式不符合W3C的某些要求,或者說違背了瀏覽器的某些規則而造成的,所以我們應該盡量通過結構或CSS的修改來達到各瀏覽器渲染一致效果,除非到了萬不得已情況下,才考慮CSS的Hack。
網上許多與CSS Hack相關的文章中說,在css的屬性值和分號之間添加字符\0,可以實現對IE 8或 IE 9的CSS hack(有的說,僅支持IE8)。
網上的示例是這樣的:
.css-hack {
color: red; /* 其他瀏覽器顯示紅色 */
color: blue\0; /* IE8、IE9 顯示藍色 */
+color: green; /* IE7 顯示綠色 */
_color: brown; /* IE6 顯示棕色 */
}
通過實際測試發現,關于使用字符\0實現的上述CSS Hack有3點需要注意。
1、IE10也能夠識別添加了字符\0的css屬性值(筆者這里沒有IE 11,不知道IE 11是否也能識別)。
2、屬性值和\0之間不能有空格,有一個空格的話(例如:blue \0),在IE 8中就失效了,僅對IE 9/IE 10有效。
3、如果我們只想對IE 8/IE 9進行CSS Hack呢?這個時候,我們去掉后面兩行與IE6、IE7有關的代碼。
.css-hack {
color: red; /* 其他瀏覽器顯示紅色 */
color: blue\0; /* IE8、IE9 顯示藍色 */
}
這個時候,在IE 6、IE 7瀏覽器中,你會發現你看到的不是紅色,而是黑色(也就是默認的字體顏色)!
這是因為一般瀏覽器的思路是,先過濾掉無效的css屬性值,然后再從正確的屬性設置中根據優先級獲取最后面的css屬性值。而IE 6/7瀏覽器不是先過濾掉無效的屬性值,而是先根據優先級,獲取最后面的css屬性值,然后再來判斷該屬性值是否,無效就忽略掉。因此,如果按照網上所說,僅僅使用\0來實現IE 8+的CSS Hack,則會對IE6/7中的顯示效果造成破壞。你必須通過額外的css屬性設置來復原IE6/7的樣式。
因為,我們不能夠簡單地下結論說,使用\0可以實現對IE 8、IE 9甚至IE 10 +的CSS Hack。
瀏覽器識別字符標準對應表
從上圖可以分析出以下幾種情況:
1.大部分特殊字符IE瀏覽器支持,其他主流瀏覽器firefox,chrome,opera,safari不支持 (opera可識別除外)。
2.\9 :所有IE瀏覽器都支持
3._和- :僅IE6支持
4.* :IE6、E7支持
5.\0 :IE8、IE9支持,opera部分支持
6.\9\0 :IE8部分支持、IE9支持
7.\0\9 :IE8、IE9支持
css hack兼容技巧
1, FF下給 div 設置 padding 后會導致 width 和 height 增加, 但IE不會.(可用!important解決)
2, 居中問題
①.垂直居中.將 line-height 設置為 當前 div 相同的高度, 再通過 vertical-align: middle.( 注意內容不要換行.)
②.水平居中. margin: 0 auto;(當然不是萬能)
3, 若需給 a 標簽內內容加上樣式, 需要設置 display: block;(常見于導航標簽)
4, FF 和 IE 對 BOX 理解的差異導致相差 2px 的還有設為 float的div在ie下 margin加倍等問題
5, ul 標簽在 FF 下面默認有 list-style 和 padding . 最好事先聲明, 以避免不必要的麻煩. (常見于導航標簽和內容列表)
6, 作為外部 wrapper 的 div 不要定死高度, 最好還加上 overflow: hidden.以達到高度自適應
7, 關于手形光標. cursor: pointer. 而hand 只適用于 IE
針對firefox ie6 ie7的css樣式
現在大部分都是用!important來hack,對于ie6和firefox測試可以正常顯示,但是ie7對!important可以正確解釋,會導致頁面沒按要求顯示!找到一個針對IE7不錯的hack方式就是使用“*+html”,現在用IE7瀏覽一下,應該沒有問題了。
現在寫一個CSS可以這樣:
#1 { color: #333; } /* Moz */
* html #1 { color: #666; } /* IE6 */
*+html #1 { color: #999; } /* IE7 */
那么在firefox下字體顏色顯示為#333,IE6下字體顏色顯示為#666,IE7下字體顏色顯示為#999。
css布局中的居中問題
主要的樣式定義如下:
body {TEXT-ALIGN: center;}
#center { MARGIN-RIGHT: auto; MARGIN-LEFT: auto; }
說明:
首先在父級元素定義TEXT-ALIGN: center;這個的意思就是在父級元素內的內容居中;對于IE這樣設定就已經可以了。
但在mozilla中不能居中。解決辦法就是在子元素定義時候設定時再加上“MARGIN-RIGHT: auto;MARGIN-LEFT: auto; ”
需要說明的是,如果你想用這個方法使整個頁面要居中,建議不要套在一個DIV里,你可以依次拆出多個div,
只要在每個拆出的div里定義MARGIN-RIGHT: auto;MARGIN-LEFT: auto; 就可以了。
盒模型不同解釋
#box{ width:600px; //for ie6.0- w\idth:500px; //for ff+ie6.0}
#box{ width:600px!important //for ff width:600px; //for ff+ie6.0 width /**/:500px; //for ie6.0-}
浮動ie產生的雙倍距離
#box{ float:left; width:100px; margin:0 0 0 100px; //這種情況之下IE會產生200px的距離 display:inline; //使浮動忽略}
這里細說一下block,inline兩個元素,Block元素的特點是:總是在新行上開始,高度,寬度,行高,邊距都可以控制(塊元素);Inline元素的特點是:和其他元素在同一行上,…不可控制(內嵌元素);
#box{ display:block; //可以為內嵌元素模擬為塊元素 display:inline; //實現同一行排列的的效果 diplay:table;
IE不認得min-這個定義,但實際上它把正常的width和height當作有min的情況來使。這樣問題就大了,如果只用寬度和高度,正常的瀏覽器里這兩個值就不會變,如果只用min-width和min-height的話,IE下面根本等于沒有設置寬度和高度。比如要設置背景圖片,這個寬度是比較重要的。要解決這個問題,可以這樣:
#box{ width: 80px; height: 35px;}html>body #box{ width: auto; height: auto; min-width: 80px; min-height: 35px;}
頁面的最小寬度
min-width是個非常方便的CSS命令,它可以指定元素最小也不能小于某個寬度,這樣就能保證排版一直正確。但IE不認得這個,而它實際上把width當做最小寬度來使。為了讓這一命令在IE上也能用,可以把一個<div> 放到 <body> 標簽下,然后為div指定一個類:
然后CSS這樣設計:
#container{ min-width: 600px; width:expression(document.body.clientWidth < 600? “600px”: “auto” );}
第一個min-width是正常的;但第2行的width使用了JavaScript,這只有IE才認得,這也會讓你的HTML文檔不太正規。它實際上通過Javascript的判斷來實現最小寬度。
清除浮動
.hackbox{ display:table; //將對象作為塊元素級的表格顯示}或者.hackbox{ clear:both;}
或者加入:after(偽對象),設置在對象后發生的內容,通常和content配合使用,IE不支持此偽對象,非Ie 瀏覽器支持,
所以并不影響到IE/WIN瀏覽器。這種的最麻煩的……
#box:after{ content: “.”; display: block; height: 0; clear: both; visibility: hidden;}
DIV浮動IE文本產生3象素的bug
左邊對象浮動,右邊采用外補丁的左邊距來定位,右邊對象內的文本會離左邊有3px的間距。
#box{ float:left; width:800px;}
#left{ float:left; width:50%;}
#right{ width:50
html #left{ margin-right:-3px; //這句是關鍵}
HTML代碼
<div id=”box”>
<div id=”left”></div>
<div id=”right”></div>
</div>
屬性選擇器(這個不能算是兼容,是隱藏css的一個bug)
p[id]{}div[id]{}
這個對于IE6.0和IE6.0以下的版本都隱藏,FF和OPera作用屬性選擇器和子選擇器還是有區別的,子選擇器的范圍從形式來說縮小了,屬性選擇器的范圍比較大,如p[id]中,所有p標簽中有id的都是同樣式的。
IE捉迷藏的問題
當div應用復雜的時候每個欄中又有一些鏈接,DIV等這個時候容易發生捉迷藏的問題。有些內容顯示不出來,當鼠標選擇這個區域是發現內容確實在頁面。
解決辦法:對#layout使用line-height屬性 或者給#layout使用固定高和寬。頁面結構盡量簡單。
高度不適應
高度不適應是當內層對象的高度發生變化時外層高度不能自動進行調節,特別是當內層對象使用
margin 或paddign 時。
例:
<div id=”box”>
<p>p對象中的內容</p>
</div>
CSS:#box {background-color:#eee; }
#box p {margin-top: 20px;margin-bottom: 20px; text-align:center; }
解決方法:在P對象上下各加2個空的div對象CSS代碼:.1{height:0px;overflow:hidden;}或者為DIV加上border屬性。