最近半忙不忙的寫了一個外包網站,網站主要功能是藝術品競拍和藝術衍生品的銷售。工程已經完成了80%左右,現在前後端代碼量已經50w行左右,我主要負責的是前端設計和前端布局。下面就先放一個網站的設計圖吧,因為涉及到甲方的“商業機密”,是以打一下馬賽克:

這篇文章主要算是我對于這個項目的總結或者說是對于這階段自己看的一些前端書或者經驗的一個總結吧,是以設計圖就不貼那麼多了。整個項目的設計圖由最開始的ui定了個首頁稿基調,剩下的界面大部分都是我在首頁稿基礎上做出來的,以後有機會再唠。ps:不過話說部落格園裡現在遍園子都是.net的文章,前端的文章除了js的,就是那些“可複制可粘貼”的源碼文,希望以後能看到更多前端好文吧。
整個網站的單界面(不包括後端)已經有3,40個了,css檔案累積下來也有10多個(這個之後會細說,這塊兒是我這個項目中做的最失敗的一部分,也是我寫這個blog的原因)。
一個一個問題的唠,我就說說自己的了解,不太對的地方歡迎交流:
一、什麼是css的架構?為什麼要做架構?
如果做的是一個小的部落格網站或者說是一個小的cms,那可能很多時候不用考慮css的架構,因為css檔案很少,總共就不到10個界面,給每個界面單獨寫樣式、單獨封一個css檔案也沒有太大的工程量。但是,如果換到這種界面數達到幾十個或者幾百個的大型網站中,css的架構就非常有必要了。而且,好的架構能夠幫助團隊共同開發,不可能說總共幾十個界面,3個前端,一人分十幾個,好,你們去寫吧,這樣的工作效率太低,而且極易導緻樣式沖突和樣式被覆寫,可能寫起來很快,每個人都很勤勞的把自己的代碼寫完了,然後後端總合之後發現樣式全亂了,一改改了好幾天,比寫都慢。
合适的css結構能夠幫助開發者減少代碼量,能夠幫助前端開發團隊在共同開發的過程中能夠更好的合作。同時它也能優化前端的整體結構,合理的css架構能夠減少css檔案數目和css檔案總大小,降低對伺服器的通路壓力。
它也能大幅度提高前端代碼的重用度和減少代碼的維護成本。對于那種1個小時想改一次界面的甲方,沒有好的css架構真是要瘋了。比如說你每個頁面都有個标題欄,每個頁面都是一個單獨的css,然後突然有一天甲方深井冰一樣說,我想改一下樣式,這時候你隻有兩個辦法:1.抱着甲方大腿哭訴求不改2.默默打開電腦開始一個界面一個界面的改。看到這裡很多有開發經驗的同志們應該都知道說,提取這個标題版塊,寫在統一的css檔案内,每個界面都引用一下,最後想改的話隻要去總的那個css檔案裡面改就可以了。這就是最簡單的子產品化,不過,子產品化的過程中還有很多問題需要注意:1.比如3個界面都有标題欄,但是3個界面對于标題欄字型顔色的要求各不相同怎麼辦?對于上下margin的要求又不相同怎麼辦?2.突然多了一個界面,它有标題欄,但是它标題欄裡多了個背景圖檔,這個怎麼解決?再麻煩一點,它标題欄裡多了一個<p>表簽,多出來的又怎麼布局?這種解決子產品之間差異的問題确實值得好好研究一下。
通常的css架構,或者是目前網站的css架構,包括了對浏覽器預設樣式的覆寫重置、對網站内部子產品的提取抽象化、約定css代碼規範、沖突解決等功能。如果項目中有引用其他的成熟架構,比如說bootstrap、yui,怎麼把這些架構和自己寫的分割開,能實作樣式而又不沖突?稍後慢慢唠。
怎麼做css架構或者怎麼實作簡單的css結構?
答:寫代碼啊!
二、css的架構從哪裡做起呢?
動手一個項目前,不能看到設計圖就直接幹,應該先想的是怎麼樣去寫。就像我們老師最常對我們說的一樣“隻會寫代碼,你隻是平庸的程式員。能夠做出好的架構或者能夠安排好項目怎麼開發的,才是高端點兒的程式員。平庸的程式員隻能吃香蕉,高端的程式員有時候還能吃點鳳梨、蘋果啥的”。直接動手開始寫,寫着寫着就會發現很多時候自己是在做重複功,不斷地複制粘貼或者是為了一個界面子產品重寫一種又一種樣式,或者寫着寫着發現“卧槽,沖突了,樣式亂了”,再或者寫着寫着發現自己寫的不對想回去改,然後開始挨個檔案的改...這種沒有架構的、笨拙的在寫css就是在幹體力活,很久之前寫的一個項目就是這樣,20幾個界面慢慢改去吧,改了整整兩天,都要瘋了...
動手一個項目前,最起碼的,應該想清楚大緻有多少個css檔案,哪些css檔案需要先寫出來一個固定版本,哪些css代碼可能會大量重用,哪些css檔案可能會有大規模的改動。然後根據這些css的詳細要求去開始動手寫初版。
比如我上面放的截圖,最直覺的header首部欄:
,在每個界面都是一樣的。當然這個我們可以在後端裡面用分布視圖layout來實作,但是在界面前端實作的初期,是不是也應該把這一塊兒的html、css、js抽離出來,這樣在後端進行最後整合的時候也能快一些,而且萬一碰到個聖誕節,客戶說給上面背景色換成藍色吧,這樣直接翻到header.css裡改一改樣式就好了,不用苦逼的去“體力活”了。
是以,第一種css前端架構設計的方式就是:按照區域劃分。
按照頁面内的元素或者子產品的區域定位,網站中可以劃分出來很多區域:header、footer、sidebar、slogan等等,針對于這些區域單獨定位能夠有效的實作分布視圖的劃分,每個區域都被抽離出來,建立一個界面的時候我們隻需要在裡面拼一拼就好了。沒記錯的話,yui就是這麼幹的。
在這個拍賣網站的css裡我沒有單獨抽離出來,因為我覺得單獨抽離成一個header.css、footer.css檔案有點贅餘,css檔案數在增多,而每個檔案内的代碼行數卻很少。這個還要根據具體代碼來看,一個footer樣式寫了幾十行的話,那就抽離成一個檔案吧。是以我在總的css檔案:layout.css裡其實是按照區域進行寫的:
。當我想要更改底部導航樣式的時候,直接就去layout.css裡往下翻找,改掉就可以了。
然而我們對界面進行分割之後發現,還是有很多代碼在大量重複出現,比如說登陸框、比如說表格、比如說文本框等等,是以有了第二種劃分方式:按照功能進行劃分。
按照功能劃分就是看元素的界面内功能是什麼,然後根據具體功能,把具有相同功能的元素、子產品抽離出來:font、color、button、form等等,這個應該是現在很多成熟架構采用的模式,比如我大bootstrap就是這麼幹的,下面是bootstrap2.3的less檔案夾的截圖,很明顯,都是一個個功能子產品,最後我們直接應用的是被全部整合壓縮的.min.css,裡面其實也還是這種結構:
按照功能劃分還是蠻爽的,因為你可以為每個功能劃分添加統一的字首,在有代碼提示的編譯器裡寫代碼簡直極速。換成那種按區域劃分的話,有時候就略微蛋疼了“哎呀,頁腳的css名是什麼?哎呀,小王寫的那塊兒側邊欄的類名是什麼”。
在這個項目的代碼裡,我其實采用的是第一種方式和第二種方式混用的模式,從我上一張css檔案截圖就能看出來,我不僅把重複出現的區域子產品的代碼抽象了出來,而且也把側邊欄、遮罩這種功能子產品給抽象整理了出來,盡量提高我的代碼的複用度。
之前還覺得自己的這個項目的架構做的不錯,但是後來越寫越坑,因為很多時候自己都是在做無用功。我犯的傻x錯誤:
1.子產品抽象有局限。比如說表單有要差一個特殊的元素,原來寫好的子產品就沒法用了,又得重頭寫一遍。
2.子產品抽象不完全。在我認為自己已經把子產品抽象做的差不多的時候就開始全力寫,寫着寫着發現,有的子產品被遺忘了,很多子產品需要一遍一遍的手寫。
3.css類名不規範說到底是子產品沒有劃分好。這個網站寫到現在,我的命名已經詞窮了,它這裡有很多界面:加入購物車、加入收藏清單、檢視購物車、确認支付、填寫确認訂單、一口價支付...沒有好的英文底子真是噩夢...是以隻能翻譯漢語名,然後駝峰命名法:addcart。其實命名法還有很多,駝峰命名法最大的好處就是可以很直覺的命名,不用考慮别的,但是駝峰命名法在子類命名的時候就比較頭疼了,一個又一個的長單詞...另一種命名方法是劃線法,為了避免麻煩直接用的下劃線沒用中杠add_cart,這種命名法對于子類命名特别爽,這個後幾篇總結的時候再唠。
------------下面---------就是------------本篇-------核心-----了---
下面就是本篇文章的【核心】了,也是我痛心疾首的反思t^t最近項目受阻、半寫不寫的狀态,是以看了一些前端代碼規範、網站前端開發的總結的書,然後發現了一種新的結構方法,看完之後真是整個人都不好了。推薦這本書《編寫高品質代碼-web前端開發修煉之道》
另一種比較推薦的css架構方法是:按照界面職能進行劃分:這裡将網站的整個前端抽象成了一個軟體或者是一個項目,這時候我們要考慮的就是項目底層是什麼,項目的表現層是什麼,類似于大家常說的mvc的思想,把前端架構也進行mvc般的劃分,可以把所有的css檔案歸納為三類:
1.base類 2.common類 3.page類
這三類并不是像區域架構、功能架構中并列作用的模式,而是以base類為底層,逐層影響,層疊作用,大概畫了個作用圖:
确實,就像這種金字塔結構,下面詳細介紹一下每個類的作用。
[1.base類]
顧名思義,基礎,它是整個css架構中最基礎的部分。它負責提供浏覽器預設樣式重置、基礎功能實作。說到base裡的基礎功能實作,它主要指的是那種涉及範圍極小、抽象程度高的原子級别的功能類實作。比如我們最常見的.f12{font-size:12px;},.mt30{margin-top:30px;},每一個原子類隻負責實作一種功能,絕對不涉及到具體的頁面ui,隻是為上幾層提供原子功能,具體某子產品的實作則有這些原子類間進行組合實作。當然,base類還要負責浏覽器預設樣式的reset,這個我覺得yui實作的就很靠譜,現在很多網站的<h123456>都是不加粗的,這個都需要提前在reset部分寫好。
base類是整個css架構的地基,所有界面都會引用整個檔案,這對這個檔案提出了要求:1.檔案大小不能過大 2.檔案可靠性要高,不能出現多個版本
3.寫成之後盡量減少維護次數或者盡量不用維護。而且不同網站的base類可以共用,因為base類不涉及任何具體的ui樣式,高度可移植。
具體base類檔案都有什麼,這個下一講來好好唠唠,今天沒空了。
[2.common類]
普通類,它是利用css基礎類實作的基礎子產品的css檔案,我們已經把整個界面裡的文字、邊距、顔色等原子工程抽離出來了,現在需要我們為目前網站定制子產品了。
設計原則裡“統一性原則”要求到同一網站必須保持風格一緻,你不可能首頁扁平化,進了清單頁就來個高光高陰影還帶酷炫flash的web2.0風格頁。是以,同一網站内的搜尋框、文本框、按鈕、清單大多數情況下都是統一風格的,是以這就給我們個機會,把這些會重複出現的子產品抽離到common類裡,類似于mvc裡面的model,也類似于我們上面講述的架構功能劃分的具體功能檔案。為了盡量保證可重用和靈活使用,我們需要對這些子產品進行完整封裝。
話說,子產品需要進行訂制時怎麼辦?
我想到了兩個辦法,一種是利用less等語言給子產品預留樣式接口,直接修改配置檔案,再動态輸出css檔案。2.盡量減少子產品的ui屬性,比如bgcolor或者是border,可以空缺,而在實際使用時根據自己的需要與原子類進行組合。但是這種方法可能會對原子類有要求而且會對base檔案産生影響,是以我自己又編出了個詞:分子類,顯而易見就是提供針對于子產品的大原子類定制,為每一個子產品定制專屬樣式類,同樣至于common層,需要定制子產品樣式時隻需要彼此組合即可。之後的文章裡寫點東西示範一下。
[3.page類]
頁面類,從圖裡也能看出來,它在金字塔的塔尖,而它的作用範圍也是最小的,就是每一個頁面,到不至于每一個頁面一個css,但是也差不多吧。
page類就是負責提供頁面級樣式的。page類css可能産生一些比較令人糾結的問題:1.page太多,是以page
css單檔案太多,每一個檔案就是一個http請求,伺服器能受得了不?2.page
css為了不多,是以合并在一個page.css裡,但是命名怎麼辦?比如.part, .one, .main,
.theme....這些頻繁出現的類名合并沖突怎麼辦?
第二個問題可以通過命名範圍限定來解決。
至于第一個問題,你可以把css單檔案合并,然後你就去看第二個問題的答案吧。
總結下來,在開發中,base和common類一般由一個人完成,在他完成這些類之後其他人接手項目,開始添些page.css,是以page層裡代碼奇多,如果應用到分布視圖,一個整頁面其實是由若幹個小界面拼起來的,那麼如何避免沖突?如何避免樣式覆寫?以後詳談。
_(:з」∠)_碼了這麼多字累死我了,今天就先寫到這。下篇見~~【求交流求師傅帶求内推求不吐槽...】
下一篇文章,咱們詳細談談base類css檔案,以及我自己對項目css的重構。
最後,最後,我想說的就是↓↓↓