日期:2010-05-19 分類:CSS
人一旦習慣了某些東西就很難去改,,以及各種各樣的原因,,新的瀏覽器越來越多,而老的總淘汰不了,。增長總是快于消亡導致了瀏覽器兼容是成了談不完的話題,。說 到瀏覽器兼容,CSS HACK自然而然地被我們想起,。今天,,我們通常都有一個團隊或者將有一個團隊的人在一個公司里面做相同的事,需要我們有統(tǒng)一的規(guī)范來進行Coding,,以 方便維護,。而解決兼容的方法就是(必須是,因為這才最容易有問題的)其中一個最重要的,、要解決的規(guī)范之一,。
在解決兼容方法上,想定出一個統(tǒng)一的規(guī)范,,個人認為應該以下面3點為基本原則:
- 權衡成本:在瀏覽器被淘汰后,,如何快速清理掉無用代碼
- 可維護:在資源成本和完美間平衡的向后兼容
- 可讀:省力、易記
這里把成本放在了第一位,,并不是說我們不愿意追求完美,,而只是,,太刻意追求完美有時候可能會阻礙我們前進;在成本后,,應該是可維護和可讀,,這點對于團隊的合作來說至關重要,,而最終結果也是為了減少成本,。
先把這三個原則存起來,來看看我們平時解決兼容的寫法(后面會附詳細的Hack方法列表):
一,、CSS 選擇器 Hack
/* Opera */
@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0)
{head~body .sofish{display:block;}}
這種寫法的優(yōu)缺點是:
- 優(yōu)點:全面,,各種HACK都有;清理無用代碼里易認
- 缺點:選擇器名稱不易記,;代碼量多(要重復寫選擇器)
二,、CSS 屬性 Hack
.sofish {
padding:10px;
padding:9px\9; /* all ie */
padding:8px\0; /* ie8-9 */
*padding:5px; /* ie6-7 */
+padding:7px; /* ie7 */
_padding:6px; /* ie6 */
}
這種寫法的優(yōu)缺點是:
三,、IE 注釋
<!--[if IE]>IE only<![endif]-->
<!--[if !IE]>NOT IE<![endif]-->
這種寫法的優(yōu)缺點是:
- 優(yōu)點:安全,;向后兼容好;易維護
- 缺點:用不好會增加HTTP請求,;用得好代碼又多
四,、瀏覽器探測:JS/后端程序判斷
// 以jQuery為例,檢測是否是IE6,,是則加上class="ie6"
if ($.browser.msie && $.browser.version = 6 ){
$('div').addClass('ie6');
}
這種寫法的優(yōu)缺點是:
- 優(yōu)點:全面,;易維護;可讀性高
- 缺點:占資源,;代碼量大(要重寫選擇器)
上面4種是我們最常用的方法?,F(xiàn)在,讓我們抽出心里存著的那3個原則,,看看如何選擇,。要時間思考一下么?這里簡單地說一下我的選擇:
- 盡量使用單獨HACK
這樣維護起來成本比較低,,改動不會影響其他的瀏覽器,,而一旦有瀏覽器淘汰,只要搜索關鍵字,,就可以批量去掉這些代碼,。比如,ie6的單獨hack:_padding:6px;,;
- 向后兼容的目標:1年
你想現(xiàn)在的網站兼容IE10么,,誰不想,但這可預見性太低了,,也可以說,,成本太高了,。暫時沒必要。不過,,IE9可能要發(fā)布了,,所以,選擇像padding:8px\0;
這樣的IE8+的hack,,在刪掉其他代碼不影響向后兼容上,,會更好;并且,,如果IE10出來,,一旦支持這個hack,而又沒有這個bug,,可能刪掉只影響2個瀏覽器,,也會更方便;
- 盡可能省資源
你要是不考慮頁面加載速度,,不考慮服務器承受能力的話,,那在向后兼容和淘汰的處理上可以做得很完美(從代碼上),但這從某種程度上,,不如不做,。
五、個人推薦寫法
其實可以糾結的還真多,,這里結合A-Grade瀏覽器的種類和HACK的種類,,寫兩種個人認為比較合理的HACK和向后兼容相兼顧的寫法,僅供大家參考的,。
經濟實惠型寫法:注重單獨的HACK,。 IE的HACK比較多,選擇省力易記的屬性HACK,;其他瀏覽器HACK少,,選擇塊狀的選擇器HACK(推薦)
.sofish {
padding:10px;
padding:9px\9; /* all ie */
padding:8px\0; /* ie8-9 目前應用于IE8的單獨hack,情況比較少 */
*padding:5px; /* ie6-7 */
+padding:7px; /* ie7 */
_padding:6px; /* ie6 */
}
/* webkit and opera */
@media all and (min-width: 0px){ .sofish{padding:11px;} }
/* webkit */
@media screen and (-webkit-min-device-pixel-ratio:0){ .sofish{padding:11px;} }
/* opera */
@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0) { .sofish{padding:11px;} }
/* firefox * /
@-moz-document url-prefix(){ .sofish{padding:11px;}} /* all firefox */
html>/**/body .sofish, x:-moz-any-link, x:default { padding:11px; } /* newest firefox */
準完美主義寫法:配合IE注釋,,一律采用選擇器HACK(選擇性推薦)
HTML: 添加body class
<!--[if IE6]--><body class="ie6"><![endif]-->
<!--[if IE7]--><body class="ie7"><![endif]-->
<!--[if IE8]--><body class="ie8"><![endif]-->
<!--[if IE9]--><body class="ie9"><![endif]-->
<!--[if !IE]--><body class="non-ie"><![endif]-->
.sofish { padding:10px;}
.non-ie .sofish { padding:12px;}
.ie9 .sofish { padding:9px;}
.ie8 .sofish { padding:8px;}
.ie7 .sofish { padding:7px;}
.ie6 .sofish { padding:6px;}
/* webkit and opera */
@media all and (min-width: 0px){ .sofish{padding:11px;} }
/* webkit */
@media screen and (-webkit-min-device-pixel-ratio:0){ .sofish{padding:11px;} }
/* opera */
@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0) { .sofish{padding:11px;} }
/* firefox */
@-moz-document url-prefix(){ .sofish{padding:11px;}} /* all firefox */
html>/**/body .sofish, x:-moz-any-link, x:default { padding:11px; } /* newest firefox */
然后,,從第二種方式我們也可以發(fā)現(xiàn)。把IE注釋用在body class上,,而不是添加單獨的<link />
或者@import
會是更好的選擇,。雖然分文件也是一種不錯的選擇,但了為頁面加載速度,,HTTP請求一個都不能浪費,。
至于利用JS或者后端程序來判斷,除非你有足夠的資源,除非你解決不了(90%不會發(fā)生),,不然,,并不推薦用。附上一個表(via),,可以參考參考:
六:全面的IE6+ / Firefox / Webkit / Opera CSS HACK列表:
/***** Selector Hacks ******/
/* IE6 and below */
* html #uno { color: red }
/* IE7 */
*:first-child+html #dos { color: red }
/* IE7, FF, Saf, Opera */
html>body #tres { color: red }
/* IE8, FF, Saf, Opera (Everything but IE 6,7) */
html>/**/body #cuatro { color: red }
/* Opera 9.27 and below, safari 2 */
html:first-child #cinco { color: red }
/* Safari 2-3 */
html[xmlns*=""] body:last-child #seis { color: red }
/* safari 3+, chrome 1+, opera9+, ff 3.5+ */
body:nth-of-type(1) #siete { color: red }
/* safari 3+, chrome 1+, opera9+, ff 3.5+ */
body:first-of-type #ocho { color: red }
/* saf3+, chrome1+ */
@media screen and (-webkit-min-device-pixel-ratio:0) {
#diez { color: red }
}
/* iPhone / mobile webkit */
@media screen and (max-device-width: 480px) {
#veintiseis { color: red }
}
/* Safari 2 - 3.1 */
html[xmlns*=""]:root #trece { color: red }
/* Safari 2 - 3.1, Opera 9.25 */
*|html[xmlns*=""] #catorce { color: red }
/* Everything but IE6-8 */
:root *> #quince { color: red }
/* IE7 */
*+html #dieciocho { color: red }
/* Firefox only. 1+ */
#veinticuatro, x:-moz-any-link { color: red }
/* Firefox 3.0+ */
#veinticinco, x:-moz-any-link, x:default { color: red }
/***** Attribute Hacks ******/
/* IE6 */
#once { _color: blue }
/* IE6, IE7 */
#doce { *color: blue; /* or #color: blue */ }
/* Everything but IE6 */
#diecisiete { color/**/: blue }
/* IE6, IE7, IE8 */
#diecinueve { color: blue\9; }
/* IE7, IE8 */
#veinte { color/*\**/: blue\9; }
/* IE6, IE7 -- acts as an !important */
#veintesiete { color: blue !ie; } /* string after ! can be anything */
其他的就不多說了,。不過,還是要提醒一下: 注釋也是很重要的,。雖然是HACK了,,但現(xiàn)實中情況有時候比想象中的復雜得多,給代碼一個注釋,,好過千言萬語,。
最后,,還是那句,,希望看到你更好的方法!