自從開(kāi)始做前端開(kāi)發(fā)以來(lái),我發(fā)現在開(kāi)發(fā)頁(yè)面的時(shí)候,總是有一個(gè)問(wèn)題十分影響自己的開(kāi)發(fā)效率,這個(gè)問(wèn)題就是css的命名,主要是指css類(lèi)選擇器的命名。這個(gè)問(wèn)題主要體現在:第一,有的內容你壓根想不出用什么名字來(lái)給它命名,因為一般命名總是考慮語(yǔ)義化,好讓其他人看到這個(gè)css類(lèi)的名字就知道它是作用于哪一個(gè)內容的,但是由于網(wǎng)頁(yè)內容的復雜性和多樣性,你很難保證每個(gè)部分都能起一個(gè)合適的名字,即使你最終迫不得已想出了一個(gè)名字,也會(huì )有這個(gè)名字是否是最合適的這種糾結存在,而且最要命的是,這個(gè)命名的過(guò)程是一項非常辛苦的腦力活動(dòng),會(huì )耗費掉很多腦細胞,這一件很不值得的事情;第二,由于命名的時(shí)候是語(yǔ)義化的命名,這一點(diǎn)可能會(huì )阻礙css代碼的重用,比如說(shuō)某一個(gè)網(wǎng)頁(yè)的內容用.title來(lái)描述它的樣式,這個(gè)title包含了2條規則,{font-size: 14px; line-height: 20px},此時(shí)網(wǎng)頁(yè)的另一個(gè)內容可能需要跟這個(gè)title具有一模一樣的樣式,但是從另一個(gè)內容所處的網(wǎng)頁(yè)位置來(lái)說(shuō),可能用.desc來(lái)命名才是更合適的選擇,這個(gè)時(shí)候,我相信喜歡語(yǔ)義化命名的人肯定會(huì )把那個(gè)內容再單獨起一個(gè)css類(lèi)desc,然后把title的樣式復制過(guò)來(lái),結果就導致css文件中會(huì )存在兩份相同的樣式規則,只是命名不同而已,這樣代碼就重復了。
解決這個(gè)問(wèn)題的方法就是采用面向屬性的css命名,把那些我們實(shí)在想不出名字的,而且沒(méi)有必要起名字的,并且可以只用單一的css屬性或者組合的單一css屬性來(lái)描述的部分,通通都用面向屬性的css類(lèi)來(lái)控制樣式,讓你從煩亂的css命名的漩渦中徹底解放出來(lái),除了提高你的工作效率,最重要的是減少你腦細胞的損耗,讓你不會(huì )那么辛苦。
首先要聲明,面向屬性的css命名這個(gè)思想不是我的原創(chuàng ),它來(lái)自于張?chǎng)涡竦牟┛汀?/a>我是當時(shí)比較糾結于css的命名問(wèn)題,然后找到了他的兩篇文章,對我重新認識css的命名以及如何組織全站的css有很多的幫助,這兩篇文章分別是:
精簡(jiǎn)高效的CSS命名準則/方法
我是如何對網(wǎng)站CSS進(jìn)行架構的
你可以先去通過(guò)他的文章了解這個(gè)命名思想的起源,再回來(lái)看我的一些總結跟應用。
這個(gè)方法,簡(jiǎn)單來(lái)說(shuō),就是直接以css屬性簡(jiǎn)寫(xiě)作為css的類(lèi)名,在使用的時(shí)候,通過(guò)使用一個(gè)或組合多個(gè)這樣的簡(jiǎn)寫(xiě)形式的css類(lèi)來(lái)達到控制樣式的目的。比如說(shuō)網(wǎng)頁(yè)中有一個(gè)網(wǎng)頁(yè)內容,是一段居中的文本,大小為12px,行高為20px,段前后間距分別為10px和15px,那么就可以定義一下這些簡(jiǎn)單的屬性類(lèi):
在頁(yè)面中使用的時(shí)候,直接組合以上這些css屬性類(lèi)即可:
這就是這種屬性命名方法的具體使用方式。
css中有很多的屬性都可以采用這種方法來(lái)命名。在張?chǎng)涡竦牟┛椭?,他把自己的這套方法總結成了一個(gè)開(kāi)源的css庫:https://github.com/zhangxinxu/zxx.lib.css/blob/master/zxx.lib.css。我們可以先從他這個(gè)庫來(lái)了解他本人是如何組織這些不同的css屬性類(lèi)的,然后再來(lái)討論這其中的一些問(wèn)題。
這是他的開(kāi)源庫中,采用面向屬性命名的全部css類(lèi)(以下代碼僅是為了閱讀本文方便才引用,如果是想在實(shí)際工作中使用,最好是關(guān)注張?chǎng)涡癖救说膅ithub或者博客,因為他會(huì )不斷地優(yōu)化自己的東西):
首先他這部分代碼里面,包含了我們在網(wǎng)頁(yè)開(kāi)發(fā)中大部分常用的css屬性,如display,height,margin,padding,border,color,font-size等。在屬性類(lèi)的命名上,基本上都是采取屬性跟屬性值的縮寫(xiě)。其他可說(shuō)明的是:
1)width除了有固定值的屬性類(lèi)定義外,還包含了百分比的屬性類(lèi)定義,畢竟這個(gè)在實(shí)際工作中也時(shí)有用到;
2)margin,border,padding由于包含上下左右相關(guān)的屬性,所以他還提供了針對上下左右單邊的屬性類(lèi),方便單獨使用。
另外他的代碼都有瀏覽器兼容性方面的考慮,所以要是在自己的工作中用的話(huà),最好是參考著(zhù)他的來(lái)。
這種方法在我使用之前,我比較顧慮的是它的可維護性。因為這些屬性類(lèi)很多都包含屬性值,比如.f12{font-size: 12px},所以在html元素的class屬性值就肯定會(huì )包含f12這樣的css屬性類(lèi)名,假如要修改的對應的屬性值該怎么辦呢?那么就需要修改三個(gè)地方才行:首先是屬性值定義的地方,第二是屬性類(lèi)名定義的地方,最后就是在html中使用的地方。當時(shí)想到這個(gè)問(wèn)題的時(shí)候,我覺(jué)得這種方法不可行,因為在實(shí)際工作中,尼瑪UI崗位的同事改設計的情況太多了,那樣的話(huà),頁(yè)面上用到這種屬性命名類(lèi)的地方都要經(jīng)常改來(lái)改去。
但是后來(lái)我發(fā)現,即使不用這種命名方法,我還是改變不了UI調整設計圖的情況,而且只要設計圖一改,甚至我的html結果以及我那些采用語(yǔ)義化命名的css類(lèi)都要改,那個(gè)麻煩程度其實(shí)比用屬性命名類(lèi)的方法更厲害,所以我最后就開(kāi)始在項目中嘗試這個(gè)方法。結果發(fā)現,其實(shí)特別好用,尤其是做些文本類(lèi)的排版,垂直布局,分欄布局,以及百分比布局等特別簡(jiǎn)單高效,前面提到的那個(gè)維護的問(wèn)題也很小。我有兩個(gè)方法來(lái)解決來(lái)那個(gè)問(wèn)題:
1)假如原先用f12,后來(lái)設計把font-size改成14px,那么我只用再增加一個(gè)f14即可,再把原先html中需要把f12替換成f14的地方,換成f14即可。如果f12沒(méi)有別的地方用到了,我會(huì )考慮把f12再刪掉。
2)假如原先用f54,由于這種屬性類(lèi)并不具備通用性,所以我可能考慮直接把f54替換成我需要的屬性類(lèi),比如f52。
在本文本部分的最后,我還會(huì )給出自己關(guān)于這種使用方法的建議以及對維護問(wèn)題的處理補充?,F在先回來(lái)再看看張?chǎng)涡竦倪@些代碼,我從個(gè)人的角度,結合自己在項目中的實(shí)際情況,來(lái)說(shuō)下需要我們改善下的地方。
1)有些采用固定值的屬性類(lèi)有多余的,也有缺少的;比如沒(méi)有.h28表示height: 28px的,.w100到.w700可能都是用不到的
2)跟顏色相關(guān)的可能大部分都不一定符合項目需求,尤其是那種做出來(lái)完全沒(méi)有任何規范的設計圖,肉眼看上去相同的顏色,實(shí)際上卻是不一樣的顏色;相同的版本,在不同的頁(yè)面,有可能也使用了不同的顏色;甚至是那種色系比較豐富的設計。這些屬性類(lèi)包括border,background,color。當然純黑色和純白色還是可以統一起來(lái)的,畢竟這兩個(gè)顏色基本上各個(gè)網(wǎng)站都會(huì )用到。
3)還有些屬性類(lèi)也是多余的,比如font-family,因為我在項目中有用less,font-family是在別的地方定義的,所以這里就不需要了。當然你要是覺(jué)得這個(gè)還是有用得著(zhù)的話(huà),可以考慮留下。
4)還可以考慮增加些其它的css屬性類(lèi),比如border-radius以及flex等。border-radius現在用的已經(jīng)很普遍了,flex在移動(dòng)端也有可以用的到的地方。這個(gè)就得根據自己的項目實(shí)際情況,慢慢增加了。
綜合以上這些內容,我對于這種面向屬性命名的方法建議如下:
1)首先肯定是得以張?chǎng)涡竦倪@套代碼為基礎;
2)對于height,line-height,font-size這三個(gè)屬性,劃分屬性類(lèi)的時(shí)候,盡量以步長(cháng)為2的等差分布來(lái)定義,如:
.h0 , .h18 , .h20 , .h22 , .h24 , .h26 , .h28 , .h30 , .h32 , .h34 , .h36 , .h38 , .h40;
.lh18 , .lh20 , .lh22 , .lh24 , .lh26 , .lh28 , .lh30 , .lh32 , .lh34 , .lh36 , .lh38 , .lh40 ;
.f12 , .f14 , .f16 , .f18 , .f20 , .f22 , .f24 , .f26 , .f28 , .f30 ;
一來(lái)是為了保證這些小范圍的的尺寸都能覆蓋到;二是為了保證各個(gè)尺寸都是偶數,方便布局。
3)對于width,100以?xún)鹊墓潭ㄖ?,可以考慮以10為步長(cháng)定義一個(gè)等差分布序列:
.w0 , .w10 , .w20 , .w30 , .w40 , .w50 , .w60 , .w70 , .w80 , .w90 , .w100
其它的固定值的屬性類(lèi)可以等到實(shí)際用到的時(shí)候再追加;
對于百分比的width,可以把10%到100%的值都定義出來(lái),然后針對1/3 , 1/4 , 1/5, 1/6 也單獨定義出來(lái),因為這些都屬于常用的一些布局比例,所以可以考慮提前定義。
4)margin跟padding的屬性類(lèi)有的可能是多余的,也有可能有缺少的,但是不能提前定義太多,可以考慮在實(shí)際用的過(guò)程中再追加;
5)border,background-color以及color可以考慮留下。由于這幾個(gè)跟顏色有關(guān),所以可以把設計圖中最常用的幾種顏色也抽出來(lái)分別定義追加進(jìn)去,假如設計師比較有經(jīng)驗的話(huà),做出來(lái)的東西就會(huì )比較規范,尤其是在通用的顏色這一塊,不會(huì )搞出很多的顏色出來(lái)。在zxx.lib.css中,已定義的border,background-color還有color都是安全色,如果是設計師的顏色,其實(shí)也能定義成屬性類(lèi),比如#7c7c7c,就可以定義成.c7c,bg7c,bd7c。
6)可以根據項目的實(shí)際情況增加border-radius以及flex等屬性類(lèi)。定義方式完全跟其它屬性一樣,如flex的:
以上這部分flex的屬性類(lèi)需結合auto-prefix這種工具來(lái)使用,因為有兼容性問(wèn)題,需要統一添加前綴。
7)關(guān)于這些面向屬性的css類(lèi)組織:
第一,按照前面的這些建議,在張?chǎng)涡竦拇a的基礎上,調整成自己的項目所需之后,就應該把這個(gè)代碼單獨存放起來(lái),作為一個(gè)像bootstrap這樣的單獨的庫來(lái)使用;
第二,在實(shí)際工作過(guò)程中,如果要增加新的css屬性類(lèi),只有在這個(gè)屬性類(lèi)有公用的價(jià)值,才能添加到第一步的公共屬性類(lèi)庫里面去,否則的話(huà),就只能在當前頁(yè)面的main css里面去寫(xiě)。
8)最后,就是在堅持沒(méi)有重復的代碼前提下,根據實(shí)際情況去追加相關(guān)的css屬性類(lèi)。有公用性的就加到單獨的庫里,沒(méi)公用性的話(huà)就追加到頁(yè)面的main css里。
這些建議,也只是我個(gè)人的使用經(jīng)驗總結,有比較多的個(gè)人想法,如果覺(jué)得不對或者有疑問(wèn)的話(huà),歡迎私信或者評論交流。本文最重要的目的是分享這種面向屬性的命名方法,我相信肯定會(huì )有朋友能夠看到這個(gè)方法的價(jià)值的。
最后在張?chǎng)涡竦拇a中,還有一部分代碼,定義了很多簡(jiǎn)單常用的css類(lèi),比如浮動(dòng),浮動(dòng)清除等等:
這些代碼也可以根據實(shí)際情況稍微調整,大部分在實(shí)際工作中都有使用到的場(chǎng)景,這里僅作引用介紹,因為使用起來(lái)也很簡(jiǎn)單的。
為了說(shuō)明這個(gè)命名方法的作用,我做了一個(gè)demo,以博客園博客列表頁(yè)來(lái)說(shuō)明如何應用這種命名方法。先來(lái)看博客列表頁(yè)的結構:
可以看到這個(gè)列表頁(yè)其實(shí)是用到了很多語(yǔ)義化的命名的css類(lèi)的,假如要用面向屬性的命名方法來(lái)定義,就會(huì )變成下面這個(gè)樣子:
實(shí)際效果如下:
相關(guān)源碼可訪(fǎng)問(wèn)以下鏈接查看:
http://liuyunzhuge.github.io/blog/css_name/html/demo.html
在以上這個(gè)實(shí)踐過(guò)程中,并沒(méi)有所有的樣式都使用這種命名方法,主要的原因是單純的屬性命名對無(wú)法對偽類(lèi)或者偽元素進(jìn)行很好的樣式控制,而正好博客園列表頁(yè)中的每個(gè)鏈接的樣式都不一樣,所以沒(méi)辦法統一。這也正是面向屬性的命名方法的一種限制情形。
雖然本文的目的是在推崇這種面向屬性的命名方法,但是你從文中的內容也可以看到,這種方法是有針對性的,前面一開(kāi)始介紹的時(shí)候就說(shuō)過(guò):
采用面向屬性的css命名,把那些我們實(shí)在想不出名字的,而且沒(méi)有必要起名字的,并且可以只用單一的css屬性或者組合的單一css屬性來(lái)描述的部分,通通都用面向屬性的css類(lèi)來(lái)控制樣式
使用這個(gè)方法的最大前提就是沒(méi)有必要起名字,并且能夠用組合的單一屬性來(lái)描述的內容,就可以這種方法來(lái)加速頁(yè)面布局的工作。像前面應用實(shí)踐介紹過(guò)的那種情形一樣,當你需要配合偽類(lèi),偽元素或者背景圖片的時(shí)候,就不太適合用這種方法。
在面向屬性的命名方法不能使用的時(shí)候,有另外兩種css的命名或者說(shuō)組織方式可以使用:
1)語(yǔ)義化的命名,在整個(gè)頁(yè)面,語(yǔ)義化的css命名還是不可獲缺的一部分,尤其是那些劃分頁(yè)面模塊的,比如.header .footer .logo等等,抽象公共樣式或者公共組件的,如.dropdown,.btn,.tab等等。這些是css模塊化,代碼重用的比較大的組織單位,如果把它們也拆分了,會(huì )使得整個(gè)站點(diǎn)的css結構非常的復雜,那樣的話(huà)還不如直接用style呢;
2)采用層級來(lái)命名,而且要多用直接子元素選擇器,雖然在張?chǎng)涡竦牟┛椭胁唤ㄗhcss有層級,但是有的時(shí)候如果不想命名,又無(wú)法用面向屬性的命名方法來(lái)解決的設計,可以考慮用層級來(lái)解決,在bootstrap的源碼中很多的css組件,比如nav,dropdown,tab等等,都是通過(guò)層級來(lái)控制的,一來(lái)是起到命名空間的作用,二來(lái)是減少對層數較深的子孫元素產(chǎn)生影響。但是層數也不能太深,最好不要超過(guò)3層,否則html結構變化之后,就會(huì )影響css代碼的結構。
本文主要是傳播面向屬性的css命名方法這種思想,由于它在我實(shí)際工作中幫助我減少了很多不必要的css命名,所以我專(zhuān)門(mén)寫(xiě)了這篇文章把它分享出來(lái)。這個(gè)里面也包含了很多自己在工作中產(chǎn)生的想法,不一定符合你自己的實(shí)際需求,要是感興趣的話(huà),可以去研究下張?chǎng)涡竦哪?篇文章,相信你自己也能夠總結出一些屬于自己的東西。感謝閱讀:)
聯(lián)系客服