我是如何對網站CSS進行架構的

品讀夜的黑發表於2015-03-18

by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=944

一、寫在前面的

都是自己積累形成的一些東西,可能帶有明顯的個人印記。不是專業內容,不是權威指南,只是展示一點自己的觀點,藉此希望能與各位優秀的同行交流看法,見解。以得到進步與提高。

二、我所知的一些過往的做法

關於如何處理網站的CSS,各個網站做法都不一樣,這隨著網站的性質及大小不同,公司前人留下的規範不同,以及CSS工程師的眼界不同而有所不同。由於我從業經歷有限,所知甚淺,只能說些膚淺業餘的內容,不準確之處歡迎指出。

就CSS檔案而言,有的網站分為header.css, body.css, footer.css,不做評價;
有的分為reset.css, main.css, content.css,不做評價;
有的分為common.css,然後每個種類的頁面一個CSS,例如home.css(主頁), album.css(相簿頁面),message.css(站內信頁面),blog.css(日誌頁面)等,不做評價;
有的分為base.css,然後每個活動頁面一個單獨的CSS,等,不做評價;
還有的直接將CSS嵌在頁面中,而非外部連結呼叫,不做評價。

這些不同的處理方法,沒有什麼正確與錯誤之分,只有適合不適合。每種方法都有其存在的道理,所以我是沒有資格做任何評價的。

就每個CSS檔案的內容而言,一般都會有一段長長的CSS reset(樣式重置),然後就是有著統一字首,命名較長的樣式內容,就像人人網的部分樣式截圖:
人人網長命名的CSS程式碼 張鑫旭-鑫空間-鑫生活

使用長命名,統一的父級命名避免樣式衝突時無可厚非的。確實!曾經我也如此。

三、我是如何對網站CSS進行架構的

首先關於CSS檔案,我一般只使用一個檔案,這無關於網站的大小,網站越大,某種意義上我這種做法的優勢與潛力就會體現的越明顯。我這種單CSS文 件的做法適合於web2.0的網站,例如像是SNS網站(開心、人人、白社會),嘀咕網,蝦米網,凡客這類網站,如果是入口網站,sorry,鐵定不適 合。

讓網站單CSS誰都會,關鍵是為何可以使用單CSS檔案,這個CSS檔案不會很大嗎,如果一個網站有400個頁面,那麼這個CSS檔案豈不要數百 K。非也,在網站頁面風格一致,在web系統結構良好的情況下,CSS檔案可以控制的非常小,而且高效能,同時頁面擴充套件性也非常好。下面就開始一點一點的 展示,內容較多,需要慢慢來~~

1、整體概述

頁面佈局與文章內容顯示需要,我將整體架構做成了一張圖片,見下圖:
張鑫旭的CSS架構內容示意圖 張鑫旭-鑫空間-鑫生活

2、關於CSS reset
CSS reset(css重置)基本上是不需要的,至少可以說80%的的CSS reset都是沒有必要的,反而增加了頁面CSS 的overwrite,尤其像開心網*{margin:0;}這樣子業餘的做法更是要不得(反而破壞了很多UI的相容性,比如說單核取方塊等)。我不是一概 鄙棄CSS reset,有些常用標籤我也是會簡單重置一下的,而且會避免overwrite(樣式重寫),以保證樣式最精簡,渲染最高效。如下程式碼示例:

body{
    line-height:1.4;
    color:#333;
    font-family:arial;
    font-size: 12px;
    background:white;
}
input,textarea,select{
    font-size:12px;
    font-size:100%;    
    font-family:arial;
    font-family:inherit;
}
body,h1,h2,h3,h4,h5,h6,p,ul,ol,form{
    margin:0;
}
h4,h5,h6{
    font-size:1em;
}
ul,ol{
    padding-left:0; 
    list-style-type:none;
}
/*image with no-border*/
a img{border:0;}
img{border:0;}

這就是我全部的CSS reset。就這些就足夠了,我是沒有遇到什麼相容性的問題,不要盲從於一些主流的做法,就這些,足夠了。

3、關於CSS通用樣式庫
我在“CSS樣式分離之再分離”一文中曾提到過CSS通用樣式庫。所謂CSS通用樣式庫就是可以在任何網站使用的CSS樣式庫。“CSS樣式分離之再分離”一文中僅僅展示了CSS同樣樣式庫的一部分,完整的通用樣式庫如下(您可以根據自己的喜好重新命名或是新增刪除部分樣式):

.l{float:left;}.r{float:right;}.cl{clear:both;}
.n{font-weight:normal; font-style:normal;}.b{font-weight:bold;}.i{font-style:italic;}
.fa{font-family:Arial;}.fg{font-family:Georgia;}.ft{font-family:Tahoma;}.fl{font-family:Lucida Console;}.fs{font-family:'宋體';}.fw{font-family:'微軟雅黑';}
.tc{text-align:center;}.tr{text-align:right;}.tl{text-align:left;}
.tdl{text-decoration:underline;}.tdn,.tdn:hover,a.tdl:hover{text-decoration:none;}
.g0{color:#000000;}.g3{color:#333333;}.g6{color:#666666;}.g9{color:#999999;}.red{color:red;}.wh{color:white;}
.f0{font-size:0;}.f10{font-size:10px;}.f12{font-size:12px;}.f13{font-size:13px;}.f14{font-size:14px;}.f16{font-size:16px;}.f20{font-size:20px;}.f24{font-size:24px;}
.vm{vertical-align:middle;}.vtb{vertical-align:text-bottom;}.vt{vertical-align:top;}.vn{vertical-align:-2px;}.vimg{margin-bottom:-3px;}
.m0{margin:0;}.ml1{margin-left:1px;}.ml2{margin-left:2px;}.ml5{margin-left:5px;}.ml10{margin-left:10px;}.ml20{margin-left:20px;}.mr1{margin-right:1;}.mr2{margin-right:2px;}.mr5{margin-right:5px;}.mr10{margin-right:10px;}.mr20{margin-right:20px;}.mt1{margin-top:1;}.mt2{margin-top:2px;}.mt5{margin-top:5px;}.mt10{margin-top:10px;}.mt20{margin-top:20px;}.mb1{margin-bottom:1px;}.mb2{margin-bottom:2px;}.mb5{margin-bottom:5px;}.mb10{margin-bottom:10px;}.mb20{margin-bottom:20px;}.ml-1{margin-left:-1px;}.mt-1{margin-top:-1px;}
.p1{padding:1px;}.pl1{padding-left:1px;}.pt1{padding-top:1px;}.pr1{padding-right:1px;}.pb1{padding-bottom:1px;}.p2{padding:2px;}.pl2{padding-left:2px;}.pt2{padding-top:2px;}.pr2{padding-right:2px;}.pb2{padding-bottom:2px;}.pl5{padding-left:5px;}.p5{padding:5px;}.pt5{padding-top:5px;}.pr5{padding-right:5px;}.pb5{padding-bottom:5px;}.p10{padding:10px;}.pl10{padding-left:10px;}.pt10{padding-top:10px;}.pr10{padding-right:10px;}.pb10{padding-bottom:10px;}.p20{padding:20px;}.pl20{padding-left:20px;}.pt20{padding-top:20px;}.pr20{padding-right:20px;}.pb20{padding-bottom:20px;}
.rel{position:relative;}.abs{position:absolute;}
.dn{display:none;}.db{display:block;}.dib{-moz-inline-stack:inline-block; display:inline-block;}.di{display:inline;}
.ovh{overflow:hidden;}.ovs{overflow:scroll;}.vh{visibility:hidden;}.vv{visibility:visible;}
.lh14{line-height:14px;}.lh16{line-height:16px;}.lh18{line-height:18px;}.lh20{line-height:20px;}.lh22{line-height:22px;}.lh24{line-height:24px;}
.fix{*zoom:1;}.fix:after,.fix:before{display:block; content:"clear"; height:0; clear:both; overflow:hidden; visibility:hidden;}.z{_zoom:1;}

上面的樣式是有簡單的分類的,某種意義上講,CSS庫與js庫屬於類似的東西。

關於此樣式庫,您可以直接在您的頁面頭部<head>標籤內嵌入如下程式碼:

<link rel="stylesheet" href="http://www.zhangxinxu.com/study/css/zxx.lib.css" type="text/css" />

如果您想下載此CSS檔案,您可以狠狠地點選這裡:zxx.lib.css(右鍵-[目標|連結另存為])。您可以隨意修改,如果能保留我的一個個人資訊,那真是感激不盡~~

4、網站CSS樣式庫
這裡的樣式是根據當前實際的專案內容指定的。例如,文字連結顏色是什麼,文字連結經過的樣式是什麼;一些常用的背景色樣式,常用的邊框樣式等,以及一些高寬等。按照我的經驗,網站CSS樣式庫又可以架構為以下幾部分:
①網站常見顏色,尤其是連結色
②網站常見背景色(我習慣用bg+顏色前2字母表示,例如.bgf7表示background:#f7f7f7;)
③網站常見邊框色,這裡類似於CSS 通用庫中的margin屬性,需拆分,例如.bbdd表示border-bottom:1px solid #ddd;每 人的命名習慣不一樣,但是儘量簡單為好,甚至您可以像Google一樣,直接兩個字母(大小寫混搭)表示。另外,一定要告知設計師,邊框取色不宜多,不能 憑感覺,要有所犧牲,也就是如果之前使用了#cecece的邊框色,後面的即使使用#d0d0d0更好看,請使用#cecece代替,這就是團隊協作。
④網站遺留的單margin屬性,例如,某一div留白較大,有個單獨的margin-top:35px的屬性,ok,這個屬性請放在網站CSS樣式庫中,以.mt35{margin-top:35px;}保留,以供之後類似佈局或需要的地方使用。
⑤網站遺留的單padding屬性,例如,雙欄自適應佈局時,無論是浮動自適應,還是絕對定位自適應,都需要使用padding-left值,此時的padding-left多單樣式,可抽取出來,以網站樣式庫的形式存在。記住,是單屬性,且不可從通用元素中抽取單獨的padding值,否則是給自己挖火坑。
⑥網站遺留的width屬性,在流體佈局思想下,寬度是有限的,是珍貴的,需好好利用。
⑦網站常用的一些height屬性,指一些高度值,例如height:18px; height:20px; height:24px; height:50px; height:100px; height:200px;等。

記住一個原則:網站通用的元素(按鈕,導航,選項卡的)的樣式千萬不能分離作為網站的CSS樣式庫。

5、網站通用小圖示樣式集
小圖示的樣式合併是普遍處理的較好的,由於其規律可循,所以經常在CSS檔案較上的位置看到有關小圖示的CSS合併樣式,這在SNS網站中很是常見。一般合併樣式部分樣式為{background:url(xx.png) no-repeat;},分離部分的樣式是{background-position:x, y;},就實現而言,我覺得沒有多少說頭,只是命名有些自己的見解。在小圖示樣式命名的時候,我的建議是不要關聯圖片的內容,比如說一個相簿的下圖示,不應該使用iAlbum這樣的命名。原因有三:
1. 思考圖片的命名殺死n多腦細胞
2. 命名較長,佔用位元組數,也就是CSS檔案大小
3. 也是最重要的,後期的維護。設想下,如果日後相簿的圖示不再被使用了,原來相簿圖示的位置可以被其他小圖示(如RSS小圖示)替換嗎?理論上可以,實際 上,我們除了必要的html替換,還需要重新修改圖示樣式的命名,即iAlbum→iRss的命名,而往往取而代之的做法是直接在後面新增新的圖示。

我目前的做法是使用一個不常用的標籤作為網站的小圖示專用標籤,例如s標籤,或是u標籤,我習慣將小圖示單獨為一個小圖示Sprite,每個圖示放 在20*20畫素的格子中。在這種情況下,我都是使用矩陣命名法。命名只關聯位置,例如,我使用u標籤作為整個網站的小圖示專用標籤,則按照圖示的位置 (假設一行20個圖示),我會依次命名為:u00,u01,u02u019,u10,u11,…u119…。這種命名的好處是不用關心到底哪個位置是那個圖示,不用擔心命名衝突,在小圖示位置以及內容更換的情況下也無需重新命名。
小圖示矩陣命名法 張鑫旭-鑫空間-鑫生活

例如,上圖中標註的u113的意思其實是u(1,13),這種小圖示命名的方法我稱之為“小圖示矩陣命名法”。此命名略有不足在於在使用小圖示時需要開啟原始檔或通過註釋準確查詢到對應的class。

6-10、網站通用樣式
這裡的“網站通用樣式”可以說與“網站通用樣式庫”最為對立的兩部分。網站通用樣式專指“獨立元素”的通用樣式,所謂“獨立元素”指的是網站通用的導航, 選單,按鈕,選項卡,文字框裝飾,圖片裝飾,圓角處理等等。這些“獨立元素”的樣式千萬不能對其進行分離並歸入“網站通用樣式庫”中,否則,日後會給你留 下無盡的痛苦的!

我幾乎從不對按鈕或是導航進行定寬,都是寬度自適應,這樣,可以大大節約Sprite背景圖片以及CSS程式碼的成本。以前多有探討,這裡不多說了。

網站通用樣式的程式碼量在整個CSS檔案中所佔據的比重是相當大的,如果您的CSS檔案中發現CSS通用樣式只佔整個CSS檔案的一小部分,尤其網站專案較大時,那就需要引起警惕,可能最後的結果就是CSS檔案超負荷,最後反而一團糟。

11、網站公共結構樣式
所謂“網站的結構樣式”主要指的是最外框div的樣式,一般限制網站的寬度(960~990不等),還有就是網站的分欄佈局樣式,這裡的樣式僅僅針對主體結構,例如left_part,或是right_part;還包括網站的頭部的一些公用結構,底部的樣式結構等。

我是強烈建議公共結構僅僅定寬定高,設定浮動屬性,切不可在結構樣式上新增margin或是padding屬性,這會使網站的公共結構的重用性大大降低!

12、單頁面的精細結構
如果上述11項您都架構的非常好,那麼您在編寫每個具體頁面的時候,就會非常輕鬆,非常迅速。因為80%~90%的樣式都可以從上面11項中直接拿來用(上述11項全部都是網站公用樣式)。

對於中型大型網站,我們可能要花3~4天甚至更多的時間分析頁面設計圖,處理CSS Sprite,架構網站的CSS,這段時間不寫任何頁面,就是處理網站(可以說是)唯一的CSS檔案。所謂“磨刀不誤砍柴功”,站在整站的角度上去思考 CSS是非常重要的,這可以讓你避免迷路,有助於寫出精簡高效的樣式程式碼。

當我們把1-11項都完成了,就開始著手寫頁面了,這時候,整個網站的頁面基本上都在你腦中了,您在下手的時候就會清除:我現在做的是哪個頁面,在 整個網站中扮演著什麼樣的地位,這個頁面的CSS對整個網站的CSS有什麼影響,這裡的樣式該怎麼處理(分離,合併還是獨立)等。

一般而言,就我個人經驗,每個頁面,即使這個頁面看上去很複雜,其程式碼開銷也是非常小的。其新增的程式碼開銷去處有三處:一是分離一些樣式歸入“網站 CSS樣式庫”中;二是凡事使用的CSS Sprite的樣式與其他樣式進行合併;三就是一些精細的複雜的樣式,這些就是CSS檔案的架構的最後一部分“單頁面的精細結構了”,何為單頁面的精細結 構,如下圖的樣式,就可以說是精細結構,需要獨立出來新寫樣式(可適當分離,注意“適當”一詞):
精細結構 張鑫旭-鑫空間-鑫生活

例如上圖滑鼠經過後顯示,紅色虛框樣式,剪刀,粗邊框投影,最優惠標示,一些按鈕等就屬於精細結構,我們需要在頁面上單獨寫一個樣式。雖然理論上, 我們使用分離也是可以實現這個效果的,但是此時html程式碼的開銷實在太大,根本就不適合使用分離,這裡就該老老實實的寫樣式。這裡的寫法,命名都應該跟 隨內容而不是屬性本身。我們可以在單一類別的頁面使用同樣的前端的字首避免樣式衝突等~~

四、關於適用性

有些東西雖然看上去好,但是卻不適用。通過上述的CSS架構,我可以把網站的樣式控制地非常的精簡與高效(當然,需要設計師與後臺工程師的通力配 合),但是,對於別人,套用此架構可能就沒有這樣的效果,可能反而會更糟。前面也提到了,這種架構是我自己摸索出來的,是根據自己的寫法,佈局思想,甚至 性格等形成的,帶有明顯的個人印記。

比方說,我是個推崇自適應佈局(流體佈局)的人,是個十足的自適應控,但是,有很大一部分同行是固定佈局(畫素級相容,有計算)。固定佈局固然有其優點,但是其CSS程式碼的消耗量以及頁面的擴充套件性我是很詬病的,顯然,這是無法應用到我這裡的架構中的。

其次,不少CSS剛入門的頁面開發工程師對CSS屬性理解不夠透徹,常會寫一些沒有必要的冗餘程式碼。對於他們而言,但CSS檔案的架構確實很吃力。

說實話,我對自己的這個CSS架構的適應性都不看好,一是自己在表達方面的火候欠缺,沒有很好的展示架構的精髓,二是因為此架構本身需要有很多的控 制,這種控制受制於設計師,網站頁面架構,CSS工程師自身的功力,一旦樣式氾濫,這種架構也就毫無意義,反而弄巧成拙;但是,一旦控制下來,那麼網站就 CSS效能這塊保證領先,而這些需要優秀的有眼界的CSS工程師來掌控,需要優秀的設計師,程式設計師通力協作。雖然全然套用我展示的這套架構會由於不熟悉或 是掌控不夠而產生問題,但是,裡面一些概念,一些思想應該能有一定的啟示作用的,這也是本文的意義所在了。

我只是個初出茅廬的小生,我知道,很多真正功力深厚的前端開發人員有著更好的更廣泛適應的前端架構,如果您有幸來到這裡,歡迎分享您的一些見解與認 識。還有,文中若有您覺得不合理的觀點,也非常歡迎通過評論或是郵件(zhangxinxu@zhangxinxu.com)的方式進行指正。我們需要在 不斷的交流中提高的。

原創文章,轉載請註明來自張鑫旭-鑫空間-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=944

相關文章