如何寫出優雅的css代碼 ?
對於同樣的項目或者是一個網頁,盡管最終每個前端開發工程師都可以實現相同的效果,但是他們所寫的代碼一定是不同的。有的優雅,看起來清晰易懂,代碼具有可拓展性,這樣的代碼有利於團隊合作和后期的維護;而有的混亂,雖然表達出了最終的效果,然而卻晦澀難懂,顯然團隊成員在讀這樣的代碼時就顯得無從下手,更不利於后期的維護了。那么如何寫出優雅的代碼呢?下面我將以一個很小的項目就以下幾個方面簡單的表達一下自己的看法,如有不妥,望批評指正。
第一部分:如何整理一個項目。
當我們接手一個表白牆的小項目時,怎么去分類整理呢?是把所有的html文件、css文件、js文件和圖片等等混亂的放在一起?好吧,那就看看這樣是什么效果吧?
可能你會覺得這沒有什么啊?文件都可以找到啊,但是你試圖在sublime編輯器中打開看看是什么效果:
(補充說明:博友@Tabweng 建議文件名不要使用中文而盡量使用英文,在此表示感謝,希望大家也可以注意這個問題。)
有沒有覺得很混亂呢?!此外,如果項目更大了呢?你需要的html文件、css文件、js文件、以及圖片的需求量更大了呢?你還能保證可以順利的找出每一個你想要的文件並編輯嗎?顯然顯然是否定的。所以對於這種項目,我的建議是可以對不同文件類型進行分類,將同一類型的文件放在一個文件夾下,再將所有文件都放到一個文件夾下,如下圖所示:
這樣,在sublime text編輯器里打開上述文件也會變得更加清晰明了,如下所示:
這樣,我們就可以很輕松的查找、編輯、維護我們的代碼了!當然,對於不同的項目,如何架構和整理是不同的,我們應該具體問題具體分析,這里只是說明了一般的小項目可以遵循的做法。
第二部分:如何寫出清晰易懂的HTML代碼
HTML規范,我在博文《HMTL代碼規范》中做了詳盡的介紹,大家有興趣可以去看看。這里我們簡單回顧一下規范並以我的看法說明寫HTML代碼的一個整體思路。
1.寫HTML時,最基礎的整體結構是不可缺少的,包括<!DOCTYPE html> <html> <meta> <title> <head><body>等等。實際上這個結構在sublime編輯器中我們只要先打出!,再按一下tab鍵即可完成。
2.HMTL的代碼結構和視覺順序基本保持一致,即按照從上到下從左到右的視覺順序寫HMTL結構。我的建議是:可以先根據視覺稿,從大局着眼,將主要的幾個部分寫出來,如header部分,main部分,side部分,footer部分,即把整個結構先搭出來,然后再逐一地向內部填寫內容,而不是先把header部分寫完然后再寫main部分,把main部分全部寫完在寫side部分...因為前者的思路會更加清晰。
3.結構層(structural layer)、表現層(behavior layer)、行為層(presentation layer)三者分開,避免內聯,即使用script將js文件引入(注意:瀏覽器渲染頁面是自上而下進行的,js文件有時多在</body>前引入,有時也會在head中引入,這一部分可以看我的博文《探究移動端開發》),使用link將css文件引入。
4.保持良好的樹形結構,即每一個塊級元素都另起一行,使用tab縮進(相對於父元素)。如果不是塊級元素,如<a><img><span>等,把他們寫在一行即可。
5. 可以在不同的部分(如header、main、footer)之間使用空行分開,而在一個模塊內不要使用多余的空行,實際上這也遵循了設計中的親密性原則。(推薦前端工程師可以看看《寫給大家看的設計書》,非常不錯)
6.在html代碼里你覺得可能不是很好理解的地方予以注釋如:<!-- 一些注釋 -->。
第三部分:如何寫出優雅的css代碼。
css的代碼是否清晰明了是非常重要的,這一部分作主要介紹。
一:css分類方法
通常一個頁面我們只引用一個css,但是對於較大的項目,我們需要把css文件進行分類。
按照css的性質和用途,我們可以將css文件分成“公共型樣式”、“特殊型樣式”、“皮膚型樣式”,並以此為順序引用。那么他們分別是什么呢?
- 公共型樣式是最為重要的部分,對於比較小的項目,我們只引入一個css,這個css的樣式即公共型樣式,一般包括:“標簽的重置和設置默認值”(以消除不同瀏覽器之間的差異)、“統一調用背景圖和清除浮動或其他需統一處理的長樣式(這樣就無需對每個進行分別的處理)”、“網站通用布局”、“通用模塊和其擴展”、“元件和其擴展”、“功能類樣式”、“皮膚類樣式”。后面會具體介紹。
- 特殊型樣式即對某個維護率較高的欄目或者某個與網站整體差異較大的頁面獨立引入這樣一個特殊型樣式,方便我們維護。
- 皮膚型樣式即產品需要換膚功能,那么我們就需要將顏色、背景等抽離出來放在這里,方便管理。
css文件我們分為了公共型樣式、特殊型樣式、皮膚型樣式,那么在css文件的內部我們又是怎么分類的呢?(此部分為重點)
- 重置和默認的css代碼。這是為了消除默認樣式和瀏覽器的差異,並設置部分標簽的初始樣式,以減少后面的重復勞動。 你可以根據自己的網站需求設置,也可以使用別人寫好的一些初始化代碼,比如:雅虎工程師提供的css初始化代碼。這一部分代碼放在css內部的最上面。
- 統一處理的css代碼。 這里可以統一調用背景圖和清除浮動(指通用性較高的布局、模塊、原件內的清楚),實際上,雅虎工程師提供的css初始化代碼中就有清除浮動的css代碼。這一部分代碼放在重置和默認的css代碼下面。
- 布局(grid): 我們將頁面分割為幾個大塊,通常有頭部、主體、主欄、側欄、尾部等。常用!
- 模塊(module):即語義化的可以重復使用的較大的整體。如導航、登陸、注冊、列表、評論、搜索等。常用!
- 元件(unit):通常是一個不可再分的較為小巧的個體,被重復用於各種模塊中,比如按鈕、輸入框、loading、圖表等。常用!
- 功能(function):為方便一些常用樣式的使用,我們將這些使用率較高的樣式剝離出來,按需使用,通常這些選擇器具有固定樣式表現,比如清除浮動。不常用,不可濫用!
- 皮膚(skin):對於換膚型網站需要使用,將皮膚型的樣式抽離出來,非換膚型網站不可濫用,不常用。
- 狀態:即一些狀態類樣式。不常用。
對於后面幾種內部分類,大家先有個印象即可,后面我會介紹其使用方法。
二、css命名規則
重要:使用類選擇器,放棄ID選擇器。因為ID在一個頁面中的唯一性導致了如果以ID為選擇器來寫css,就無法重用,而class而優勢在於復用性,而且私有度也並不高。因此,我一般情況下會選擇在HTML中的ID用於JavaScript,但是在CSS里只用class,一個ID也不用。這樣做實際上也是將表現和行為分開,而不是混在一起。
在html文件中寫class的方法:使用單個字母+“-”為前綴。比如:對於header部分,我們可以這樣寫:
<div class="g-header"></div>
那么“單個字母”是什么呢? 實際上就是剛剛介紹的css內部分類方法中的布局(grid)的第一個字母,好處是我們在css代碼中可以通過首字母清楚地知道其作用是什么,即見名知意。由此可知,對於模塊化(module)的部分我們可以這樣寫:<div class="m-log"></div>。此div即為登陸框這個模塊。 對於元件部分,即不可再分的個體,我們可以這樣寫<img class="u-img" src="../images/iam.png" alt="pic">。對於功能(function)部分,我們就可以這么寫:<div class="f-clearFloat"></div>。對於皮膚(skin)部分,我們可以這么寫:<div class="s-changeSkin">。 其中 g、m、u這三個首字母是我們用的最多的首字母,其他的首字母應該根據情況來使用。注意1:在css中,樣式的選擇器總是要以上面的 .g- .m- .u- .f- .s-這五類開頭,然后再里面使用后代選擇器。 注意2:這並不是說所有的className都需要加這些前綴,對於一些不屬於這幾種的元素,我們完全可以不加前綴,作為后代選擇器使用。
那么后代選擇器要怎么使用呢? 我們約定不以單個字母+“-”為前綴且長度大於等於2的類選擇器為后代選擇器。如:.g-date .u-rightArrow{ float: right;} 這個就是不合適的,我們直接寫成 .u-rightArrow{ float: right;}即可。 且一個語義化的標簽也可以是后代選擇器。比如.m-list li{}。 上一句話也就是說不是語義化的標簽作為后代選擇器是不合適的,如:.m-list div{},這樣的寫法很有可能造成污染。
除此之外,我們應當注意:在命名時應當盡量簡約而不失語義。如下所示:
對於相同語義的不同類命名,我們可以直接加數字或字母區分即可(如.m-list1、.m-list2,都是列表模塊,都通加數字即表示不同的列表模塊)。
三:css代碼格式
1.選擇器、屬性和值都是用小寫。
這一點非常關鍵:根據xhtml規范,所有的標簽屬性和值都要使用小寫形式,而我們知道xhtml更為標准,所以最好遵循之,這樣,選擇器必須小寫就是十分必要的了。既然這樣我們就不能使用駝峰式寫法來寫類名了,如class="u-leftArrow"實際上就是不規范的了,最好寫成class="u-left_arrow",也可以表達相同的意思。
2.單行寫完一個選擇器定義。
優點:便於選擇器的尋找和閱讀,也便於插入新的選擇器和編輯,便於模塊等的識別。更重要的是可以去除多余空格,使代碼緊湊減少換行。試想,如果每一行只有一個屬性名和屬性值,那么對於一個大項目而言,就很難做到選擇器的尋找和閱讀了,而使用一行寫完一個選擇器,那么就有可能縮短為1/6到1/10,這還是非常客觀的。
3.最后一個值也要一分號結尾。
實際上,在大括號結束前的值可以省略分號,但是這樣做會對修改、添加和維護工作帶來不必要的失誤和麻煩。比如,在最后添加一個屬性,如果之前沒有在末尾添加分號,那么你就要在新添加的屬性前添加分號,否則就會出錯,比如在我的一篇博文為解決中文字體顯示為方框添加JSON數據時就出現過此類問題。
4.省略值為0的單位
優點:可以節省不必要的字節同時也為了方便閱讀,我們將0px、0em、0%等都縮寫為0.如下所示:
.m-box{margin:0 10px; backgrond-position:50% 0;}
5.使用16進制表示顏色值,其中的字母使用大寫形式,並盡量縮寫。
除非在你需要透明度而使用rgba,否則都是用#FFFFFF這樣的寫法,並盡量縮寫,如#FFF。使用大寫形式,是因為這樣更加具有易讀性,且有利於壓縮,而縮寫為了減少不必要的字節。
(補充說明:博友@batsing 指出在PC端使用16進制表示顏色,IE8及以下不兼容,在此表示感謝,希望大家也可以注意這個問題。)
6.根據屬性的重要性順序書寫。
在上面的第二點我們說到應當在單行寫完一個選擇器。如果我們不遵循一定的書寫順序,那么寫出來的代碼一定是混亂的,那么怎么才能寫出優雅的css代碼呢?這時就需要根據屬性的重要性順序書寫。如下圖所示:
注意:只遵循橫向順序即可,即先書寫定位布局類屬性,在書寫盒模型等自身屬性,最后書寫文本類及修飾類屬性。 另外,如果屬性間存在關聯性,則不要隔開寫,如下所示。
.m-box{position:relative;height:20px;line-height:20px; padding:5px;color:#000;}
其中的height和line-height具有關聯性,我們盡量不要分開寫。
7.私有在前,標准在后。
先寫帶有瀏覽器私有標志的屬性,后寫W3C標准的屬性。因為私有的屬性,說明瀏覽器自身還沒有規范化,標准屬性是用不了的。若某一天該瀏覽器的屬性規范化了,那么說明標准屬性可以使用了,而如果我們先寫W3C標准屬性,最后寫私有屬性,就有可能導致私有屬性覆蓋標准屬性。因此私有在前,標准在后的寫法是考慮到了以后可能會出現的問題。
如:
.m-box{-webkit-box-shadow:0 0 0 #000;-moz-box-shadow:0 0 0 #000;box-shadow:0 0 0 #000;}
8.選擇器等級
!important>行內樣式style>id選擇器>類、偽類和屬性選擇器>標簽選擇器和偽元素選擇器
9.css內部的順序
我認為,對於一個網頁而言,我們在寫css時,可以分為幾個部分來寫,比如header部分的css代碼,main部分的css代碼,部分之間通過空格隔開並給以響應的注釋,這樣更有利於我們的閱讀和后期的維護,如下所示。
10.優化方案:對於可以縮寫的值我們盡量采用縮寫形式,這樣有利於減小css文件大小,並增加可讀性和可維護性。且最好盡量減少沒有實際作用的冗余的屬性。有時我們會將定義相同的或者有大部分屬性值相同的一系列的選擇器組合到一起(采用逗號的方法)來統一定義,這樣可以為你節省很多字節和寶貴時間。
四.類選擇器的命名建議
在前面說到,命名className時,應當以其作用、功能來命名,而不要使用沒有語義化或者以顏色、左右空間位置的文字來命名。
1. 對於布局,即用.g-作為前綴,通常有以下推薦的寫法。
頭部: header或head
主體: body
尾部:footer或foot
主欄: main
側欄:side
盒容器: wrap或box
主欄子容器:mainc
側欄子容器:sidec
2.對於模塊,即.m-作為前綴。元件,.u-作為前綴,通常有下面推薦的寫法。
導航: nav
子導航:subnav
菜單:menu
選項卡:tab
標題區:head或title
內容區:body或content
列表:list
表格:table
表單:form
排行:top
熱點:hot
登錄:login
標志:logo
廣告:adervertise
搜索:search
幻燈:slide
幫助:help
新聞:news
下載:download
注冊:register或regist
投票:vote
版權:copyright
結果:result
按鈕:button
輸入:input
3.對於功能,即以.f-為前綴,通常推薦如下:
清除浮動:clearboth
向左浮動:floatleft
向右浮動: floatright
溢出隱藏:overflowhidden
4.對於顏色,即以.s-為前綴,通常推薦如下:
字體顏色:fontcolor
背景:background
背景顏色:backgroundcolor
背景圖片:backgroundimage
背景定位:backgroundposition
邊框顏色:bordercolor
5.對於狀態,即以.z-為前綴,通常推薦如下:
選中:selected
當前:current
顯示:show
隱藏:hide
打開:open
關閉:close
出錯:error
不可用:disabled
五、使用css選擇器常出現的錯誤。
- .class{} 不可用一個沒有類別的樣式作為主選擇器,它只能作為后代選擇器
- .m-xxx div{} 不可用沒有語義的便簽作為選擇器,會造成大面積污染
- .g-zzz .m-xxx{} 一般類別的選擇器的后代選擇中不應當包括類別選擇器
- .m-xxx .main .mainc .nav li{} 不要將選擇器寫的過於冗長,因為選擇器的結構越復雜,瀏覽器的消耗就越大,建議在3個長度之內寫完。
補充內容:
http://www.cnblogs.com/hustskyking/p/css-spec.html
努力的人,運氣一般不會太差~