前端通用性設計——CSS的跨瀏覽器兼容,人雲亦雲篇

Leave a Comment Posted by jeffery on 2010-06-22, under xhtml+css

這標題,起得有點唬人哇。原先打算自成一篇的,但是,大概想了一下,CSS的瀏覽器兼容問題,應該也可以算是前端通用設計中的一部分吧。當然,這個問題的歸屬,當然是見仁見智了。

CSS的兼容問題,一定讓不少人很頭疼吧,特別是初識html、css的小盆友,即使是進階中的中盆友大概也是會很鬱悶的吧。網路上很多關於CSS兼容的篇章,幾乎都是以說教的口吻在說的,權衡了一下,我沒說教的資本,只能是分享一下自己的經驗啦,既然是經驗之談,難免會有錯誤和不被認可的言論,如果你覺得我是在胡扯,那你也可以移步他處了,不是說不歡迎你,而是你沒必要在這裡浪費時間。另外,這裡不會說什麼技巧之類的東西。

另外,我寫東西很拖沓,常常胡言亂語不著重點,所以寫到這裡,依然還沒進入主題,不耐煩的盆友,你們可以移步他處了。嗯,要怎麼進入主題呢,先說一個不相關的問題吧。

遇到瀏覽器兼容問題的盆友,在想怎麼做兼容之前,不妨想想為什麼要做兼容。幹這一行,有一個最基本的知識是必需要知道的,由於歷史原因,在瀏覽器大戰後,逐漸趨於緩和的瀏覽器市場,一直都是暗流涌動。各家瀏覽器廠商除了當時各自加入的新特性外,也不斷的為了使自家的產品符合W3C的標準,而不斷的在向W3C靠攏。由於W3C對標準的描述并非非常的到位,導致各廠商的文字工作者在理解W3C標準時,產生的或多或少的偏差,這就是CSS Hack出現的基本原因——各瀏覽器對W3C標準的理解偏差,導致瀏覽器在渲染同一個模型時,出現不同的渲染方式。

我在之前任職的公司,前端頁面的瀏覽器兼容是有要求的,要最大限度的充分考慮IE6用戶的感受,某些特殊頁面,還需要考慮正在使用IE5.5的老伯伯的問題。因為公司營維部門有統計數字給我們做支撐,所以我們非常容易知道需要照顧哪一些用戶。總的來說,使用IE6的用戶,佔了80%左右,IE7/IE8在12%左右,使用IE5.5的老伯伯,仍然有2%的份額,其他瀏覽器用戶,相對來說,灰常少。但是有個特點,就是opera和firefox的用戶,在我們的年度統計中,是一直處于增長狀態的,也就是說,在未來的2-3年間,他們也許會成長為我們的主要用戶,所以我們要特別關照他們,給他們一些甜頭(所謂的甜頭,其實就是按W3C的標準來寫我們的頁面)。

看了上面兩段,對於為什麼要做CSS兼容,你大概已經心中有數了吧?在現今最常被人使用的瀏覽器中,對W3C標準實現得最好的有opera、firefox、webkit核心瀏覽器(包括google和apple)、IE8也算吧,雖然在渲染的時候常有怪異表現,不過比起IE7,那可是非常好用的。如前所言,CSS兼容的要點,無非就是,讓標準瀏覽器達到你最想要的效果,然後再去考慮非標準瀏覽器。

CSS瀏覽器兼容的難點,其實應該是對IE的兼容(IE8對標準的支持已經比它的前輩強多了,即將發布的IE9,據說會完美實現W3C標準)。之所以這麼說,是因為,只要你有良好的代碼編寫習慣、正確的標籤嵌套、正確的理解盒子模型,那,對標準瀏覽器,幾乎是不存在不兼容的問題的。

貌似網路上的文章,一說到CSS的瀏覽器兼容,都是逮著盒子模型一往死裡說,既然這樣,我也跟風一把好了。因為我懶得貼圖,所以只好用一個加法式子來表述,這個式子是這樣的:margin+border+padding+width(content width)+padding+border+margin。這個式子,我自認為應該可以很好的表述盒子模型了,雖然還差了上、下兩邊的描述。從這個式子裡,你應該可以看出margin、border、padding、width之間的層次,確切的說,應該是包圍層次(和z-index不是同一個概念,只是x和y軸上的方向)。對於這個式子中的content width我需要做一下解釋。在IE6時代,IE6的盒子的width,就是以上面這個式子來計算的,你在CSS中寫明的容器的width:220px,實際上是content的width;而用於佈局的整個容器的width實際上就是這個式子計算出來的總和。但是非IE系的瀏覽器不會這麼計算,它們會把border看成是width的一部分,而不是另外計算。(有人告訴我,其實它們和IE是同一個計算方法)但是,因為我很懶,所以對IE和非IE系的瀏覽器,都是用的這個式子來解決width問題,所以比較討巧的規避了一些因為width引起的亂七八糟的問題,比如,在FF下能一行顯示完的三個DIV為什麼在IE下要用兩行來顯示。

有些盆友,遇到的CSS不兼容問題,常常是因為不正確的標籤嵌套引起的。舉例來說,就是用inline元素嵌套block元素。這種標籤的嵌套方式,其實是不被允許的,但是,因為瀏覽器的大度,它不會否認這種嵌套層次,而是嘗試去渲染,這樣子,問題就出來了。我們先來理解一下,什麼是inline元素,什麼是block元素。簡單的說,inline元素不會自動填充瀏覽器的可視區域寬度,它的寬度是隨著自身包含的文本長度來確定的,inline元素不能嵌套自身和block元素;block元素會自動100%填充瀏覽器的可視區域寬度,它的寬度不會因為自身包含的文本長度而改變,block元素可以嵌套任何inline元素,以及自身或者其他block元素。inline元素還有一個特性,兩個相鄰的inline元素,第二個會跟著第一個的結尾顯示;block元素則是換行顯示第二個block元素,即使這兩個元素的寬度之和不足以填滿瀏覽器的可視區域。

現在,你應該對inline和block元素有個大概的了解了吧。我猜,你一定會問,如果我要block元素也能像inline元素一樣,能夠頭尾相接的顯示;或者,inline元素也能像block元素一樣,寬度不受包含的文本內容的影響,應該怎麼做呢?其實,有一個叫做display:inline-block的屬性值對,不應該被你忽略。但是,目前能完美實現的,只有standard模式下的IE8和非IE系的瀏覽器,話雖如此,IE6想要實現,其實也比較容易:display:inline;zoom:1;同時使用這兩個,也可得到和inline-block相似的效果。合理的利用這個屬性,可以減少一些不必要的css hack。

順便提一點,有些盆友,喜歡在做超文本鏈接時,使用text-indent:-9999em;這個方法,但是IE6有時根本不買賬。如果你使用這個屬性的是一個inline元素,它會把你的整個標籤都-9999em了,即使你把inline元素聲明為block元素也不會有好轉。使用inline-block,改變你的顯示模式,再配合line-height,就可以比較完美的隱藏文字,同時還可以規避一些莫名的問題。

網路上有些文章,喜歡推薦別人使用CSS Reset,我的經驗是,如果你不了解這是什麼東西,裡面寫的定義都有什麼用,那你還是乖乖的用body,ul,ol,img{margin:0;padding:0;border:0 none}這種方式來重置一些你知道的標籤樣式。

關於float所能引起的問題,在IE6下已經不是什麼新鮮事了,網路上有很多相關的介紹,想知道的,自己搜一下吧。總之有一條,用完後記得clear,保你省心又省事。

最後,再說一點題外話,如果你想跟風,判IE6死刑,那你最好想清楚了再做。最好的辦法不是讓用戶根本無法訪問你的站點而去下載你那個框框裡推薦的什麼狗P瀏覽器,而是讓IE6用戶能從一個樸實的界面裡看到他來你的站點想看到的東西,順便在某個稍微醒目又不會打擾到看文章的用戶的地方,放上一句提醒:如果您願意在更華麗麗的界面中暢享閱讀的樂趣,建議更換支持華麗麗界面的瀏覽器,比如:xxx。一直在叫囂用戶體驗的你,如果連這點都做不到,就不要談什麼用戶體驗了。

寫到這裡,你一定看得很失望,這是一篇什麼狗P東西,完全沒有告訴我我想要的東西嘛!如果你有這種感覺的話,那我只好說抱歉,我一向不喜歡直接把答案說出來;如果你在看這篇狗P東西之前,有瀏覽過網路上其他相關的內容,你會明白,我想說的,其實只是我的一些工作習慣而已。

本來想這樣就結束算了,想想還是寫一下結語吧。現在做前端的盆友,都比較急燥,老覺得IE系的瀏覽器(特別是IE6)和他過不去,覺得如果IE系的瀏覽器統統死掉,那頁面寫起來會爽很多。瀏覽器廠商商業運作上的事情,我們不討論,給IE系瀏覽器做兼容,其實不是一件很難的事情,對於做前端的人來說,可以算是舉手之勞。瀏覽器的兼容問題,其實很簡單,我再重複一下:只要你有良好的代碼編寫習慣、正確的標籤嵌套、正確的理解盒子模型、對標籤\css屬性能夠理解得透。這四點,如果都具備了,你要做的CSS兼容工作,就可以大大減少。

tags: ,  

留下评论