[css] 【转载】 精简高效的CSS命名准则/方法
原文鏈接:http://www.zhangxinxu.com/wordpress/2010/09/%E7%B2%BE%E7%AE%80%E9%AB%98%E6%95%88%E7%9A%84css%E5%91%BD%E5%90%8D%E5%87%86%E5%88%99%E6%96%B9%E6%B3%95/
一、“無(wú)”的哲學(xué)
佛家講究“因果報(bào)應(yīng)”,有果必有應(yīng)。此段看似與主題沒有血緣關(guān)系,實(shí)際講的是“因”。
我個(gè)人比較喜歡老子的道家思想,并喜歡以其思想解釋學(xué)習(xí)與工作中遇到的一些問(wèn)題。例如我之前寫過(guò)的“中國(guó)古代道家思想與網(wǎng)頁(yè)重構(gòu)的思考”一文。
老子有云:“天下萬(wàn)物生于有,有生于無(wú)”。具體解釋就是:天下萬(wàn)物都是由看得見的具體事物(“有”)產(chǎn)生的,而看得見的具體事物(“有”)又是由看不見的,無(wú)形無(wú)狀的東西(“無(wú)”)產(chǎn)生的,這個(gè)看不見的“無(wú)”也就是“道”,或叫做“根”、“母”。
我們看武俠片,經(jīng)常聽到“無(wú)招勝有招”這句話,這也是道家“無(wú)”之思想之體現(xiàn)。因?yàn)槟阈闹袥]有招式,你才能有無(wú)限的可能,生成其他的招式以克敵,即所謂以不變應(yīng)萬(wàn)變;相反,如果你心中牢記一套“華山劍法”,當(dāng)你與人交手時(shí),勢(shì)必按照此套路走,要是遇到相克之劍法,結(jié)局就是一敗涂地。“無(wú)招”是一種境界,是你功夫修煉到一定程度才能領(lǐng)悟到的。我們這代人應(yīng)該都看過(guò)李連杰主演的《倚天屠龍記魔教教主》,其中張三豐老頭教完張無(wú)忌太極拳后問(wèn)他“記住了沒?”張無(wú)忌一句“全忘記了!”讓人印象深刻。這就是“無(wú)”的境界。
這種境界我是深有體會(huì)的。例如每逢大考之前,我總是把以前做過(guò)的題目全部忘掉,這樣,考試時(shí)就能思如泉涌;反而是強(qiáng)記題目的做法限制了發(fā)揮。這就好比發(fā)射炮彈,炮管里提前預(yù)裝了重型炸蛋,結(jié)果戰(zhàn)斗開始時(shí),發(fā)現(xiàn)需要的是煙霧彈,此時(shí),反而被預(yù)裝的炸蛋給阻塞限制了。打籃球也有這種體會(huì),如果心中記得的是動(dòng)作,我要這么走,然后這么做,往往表現(xiàn)不佳。反而是腦中什么想法也沒有,全靠下意識(shí)行動(dòng),那真是所向披靡,得分如探囊取物。
可見,要想發(fā)揮更大,就需要“無(wú)”,把一些“限制的東西”通通去掉。沒有限制才能發(fā)揮出最大的潛能。站在最簡(jiǎn)單,最原始的那個(gè)點(diǎn)上,你才能自由馳騁,應(yīng)變自如。
二、名字的本質(zhì)是什么
我們有沒有思考過(guò)這么一個(gè)問(wèn)題:名字的本質(zhì)是什么?
這個(gè)問(wèn)題其實(shí)不難,名字本質(zhì)上就是一個(gè)符號(hào),用來(lái)區(qū)分人與人的。與符號(hào)一樣,名字本身就蘊(yùn)含著很多的信息。舉個(gè)例子,我的名字:張?chǎng)涡瘛F渲刑N(yùn)含的信息有:我老爸也姓張,我是上午太陽(yáng)剛剛升起的時(shí)候出生的,我五行缺金。一個(gè)名字,如果其蘊(yùn)含的信息越多,則這個(gè)名字就越獨(dú)特,也就是說(shuō),越不可能被別人使用;相反如果這個(gè)名字很普通,例如李娜、張艷之類,就會(huì)被大規(guī)模的重用,OK,這其實(shí)沒什么大不了的,我們的唯一身份標(biāo)識(shí)不是名字,而是身份證,但是,對(duì)于CSS樣式的命名,沖突與否可不是拉便便,擦個(gè)屁股就沒事的。
對(duì)于CSS,為了避免樣式?jīng)_突,我們總會(huì)給其賦予相當(dāng)特殊的命名,或是在選擇符上添加HTML標(biāo)記,或是使用層級(jí)。所謂一朝怕蛇咬,十年怕井繩。一旦我們經(jīng)歷過(guò)樣式?jīng)_突帶來(lái)的讓人吐血的麻煩后,我們可能就會(huì)時(shí)時(shí)在避免沖突上狠做文章,所謂過(guò)猶不及,結(jié)果又是一個(gè)爛攤子,本如花似玉的黃花小閨女變成個(gè)臃腫的肥妞。例如下面人人網(wǎng)的CSS命名:
我想我們都希望寫出精簡(jiǎn)高效的CSS代碼,如果CSS重用性越高,想必就越高效。這如人的名字一樣,如果名字越普通,越?jīng)]有含義,越容易被重用,所以CSS要想重用性高,就需要命名簡(jiǎn)單。但是,簡(jiǎn)單的命名越容易造成樣式?jīng)_突,例如.more{}。從這點(diǎn)上來(lái)說(shuō),重用性與樣式?jīng)_突時(shí)兩個(gè)對(duì)立的矛盾體。
不過(guò),萬(wàn)幸的是,這種矛盾并不是不可調(diào)和的。記住一些準(zhǔn)則/方法,CSS既可以有高度的重用性,又不會(huì)有樣式?jīng)_突的困擾。下面就將介紹這些命名方法。
三、面向?qū)傩缘拿椒?/h3>
我們習(xí)慣在CSS命名的時(shí)候摻雜語(yǔ)義,這樣可以讓代碼更易懂。例如淘寶首頁(yè)“免費(fèi)注冊(cè)”按鈕上的class名稱:help-guest-regist
上面的class命名語(yǔ)義就很明顯,獨(dú)眼龍看告示——一目了然,”help-guest-regist”就是”幫助-顧客-注冊(cè)”,很nice,很人性化的命名。作為在單一的首頁(yè)上使用,我是很難挑出什么毛病來(lái)的。
但是,從道家“無(wú)”的哲學(xué)思想來(lái)看,語(yǔ)義其實(shí)是對(duì)自身的一種束縛,越是語(yǔ)義強(qiáng)烈的命名越是沒有重用性(尤其是內(nèi)容語(yǔ)義的)。舉個(gè)實(shí)際點(diǎn)的例子,例如人人網(wǎng)的右側(cè)邊欄的標(biāo)題://zxx:一般找這類反例我就喜歡找人人網(wǎng)還有新浪,基本上一找一個(gè)準(zhǔn)。人人網(wǎng)雖然外表長(zhǎng)得跟facebook類似,但是就CSS而言,差距不是一兩個(gè)檔次的。
這個(gè)標(biāo)題的class名是”side-item-header”,樣式如下圖所示:
現(xiàn)在一切ok,現(xiàn)在設(shè)想下,如果頁(yè)面中間的模塊有個(gè)標(biāo)題,其樣式也是:
{padding:0 0 8px; text-align:right;}那你發(fā)現(xiàn)前面已經(jīng)有一模一樣的CSS樣式后,你會(huì)怎么辦。把中間的標(biāo)題也用”side-item-header”這個(gè)class嗎?這里”side”就是表示“邊”的意思,這就意味著這個(gè)樣式用在非側(cè)邊欄就是不合理的。你能做的估計(jì)即使新命名一個(gè)class,就像是”body-item-header”,明明是同樣的CSS屬性,結(jié)果卻不能重用(即使使用標(biāo)識(shí)符組合并CSS,這里的命名也是沒有重用的)。
可見命名不合理會(huì)大大限制你的CSS重用性。如何命名才能讓CSS發(fā)揮最大的重用性潛力呢?答案就是“面向?qū)傩缘拿?/strong>”。這種命名就是要讓你把頁(yè)面啊設(shè)計(jì)啊什么的通通塞到馬桶里沖走,不要管頁(yè)面什么位置,什么內(nèi)容,there is noting, 這兒什么都沒有,既然什么都沒有,也就沒有了任何限制,于是CSS可以自由出入于任何地方,無(wú)限重用,而且不用擔(dān)心沖突,因?yàn)椤懊嫦驅(qū)傩缘拿本褪轻槍?duì)自身屬性的一種命名方式,只會(huì)overwrite,不會(huì)沖突。
相比很多同行都用過(guò)這樣的命名方式,只是不夠系統(tǒng),不夠大膽、徹底,多淺嘗輒止,比如像是開心網(wǎng),還有時(shí)光網(wǎng)的CSS代碼的前面一部分樣式命名:
我在“CSS樣式分離之再分離”一文中就展示過(guò)這種命名了,分離為什么可以讓樣式的重用性放大至最大,就是因?yàn)榉蛛x后樣式的命名就是樣式本身。
就拿上面人人網(wǎng)的標(biāo)題樣式舉例,人人網(wǎng)的做法是:
.side-item-header{padding:0 0 8px; text-align:right;}要是我,我會(huì)對(duì)其進(jìn)行分離。在實(shí)際項(xiàng)目時(shí),text-align:right;這個(gè)屬性早就在CSS通用樣式庫(kù)里面了,而padding:0 0 8px;則會(huì)以padding-bottom:8px;的形式放在網(wǎng)站通用樣式庫(kù)里了(詳細(xì)請(qǐng)參見我的“我是如何對(duì)網(wǎng)站CSS進(jìn)行架構(gòu)的”一文)。最后,CSS命名與樣式會(huì)如下:
.tr{text-align:right;} .pb8{padding-bottom:8px;}而這里分離出來(lái)的樣式又可以被其他地方使用。是不是有點(diǎn)“吸星大法”的感覺。
當(dāng)然,如果網(wǎng)站本身的架構(gòu)不是對(duì)每個(gè)側(cè)欄內(nèi)容進(jìn)行模塊化處理的話,說(shuō)實(shí)話,這里標(biāo)題的分離還是有點(diǎn)危險(xiǎn)的。想想看,如果那天產(chǎn)品經(jīng)理說(shuō)底部padding值要改成10像素,啊哦,如果你的網(wǎng)站架構(gòu)不合理,含這類標(biāo)題的模塊到處塞,會(huì)改到你急火攻心,吐血三升而亡的。所以,對(duì)于分離,我反復(fù)強(qiáng)調(diào),“千萬(wàn)不要對(duì)網(wǎng)站通用的元素進(jìn)行分離”。
所以,記住精簡(jiǎn)高效的CSS命名準(zhǔn)則之一:對(duì)于網(wǎng)站非通用元素,如果樣式簡(jiǎn)單(1~2個(gè)屬性),對(duì)其分離并使用面向?qū)傩缘拿椒ā?/strong>
四、精簡(jiǎn)高效CSS命名之“三無(wú)原則”
此“三無(wú)原則”就是:無(wú)ID,無(wú)層級(jí),無(wú)標(biāo)簽
CSS命名就應(yīng)該最簡(jiǎn)單、最直接,直搗黃龍。沒有HTML標(biāo)簽,沒有層級(jí),這些通通滾蛋,不要。為什么不要,有三大原因:
1. 限制重用
我們會(huì)使用層級(jí)(#test .test),會(huì)使用標(biāo)簽(ul.test),可能是習(xí)慣(沒多想),或是為了避免沖突。但是,我跟你說(shuō),從今以后,這種寫法讓他見鬼去吧(如果不是為了改變CSS優(yōu)先級(jí)的話)。正如開篇論述的哲學(xué)觀點(diǎn),你限制越多,越抑制了CSS的重用性。例如#test .test{}這種寫法,里面的CSS重用性多大,完全限死在了id為test的元素下,哪有重用性可言;又如ul.test,我勒個(gè)去,這個(gè)ul標(biāo)簽十有八九就是裝飾用的,往這兒一放,同樣CSS樣式的div標(biāo)簽可以用嗎?哭爹喊娘,眼淚汪汪也不管用啊。所以,相信我,層級(jí)啊,標(biāo)簽啊什么的,通通見鬼去吧。要知道,層級(jí)啊,標(biāo)簽啊作用是什么,是用來(lái)提高CSS優(yōu)先級(jí),把那個(gè)字母長(zhǎng)的讓人發(fā)毛的”!important”干掉的。
2. CSS文件大小
這瓜子雖小,吃多了也是可以填飽肚子的。所以,你的CSS名稱不要像老太太的裹腳布一樣,搞得又臭又長(zhǎng),如下圖所示的人人網(wǎng)那個(gè)冗長(zhǎng)的CSS命名吧:
你看名稱的字節(jié)數(shù)已經(jīng)比屬性還大了,要是這些名稱都在15字符以內(nèi),乖乖,這個(gè)CSS文件可以小個(gè)1~2K絕對(duì)沒有問(wèn)題的。你看下圖這樣子的命名,這樣子的CSS排版是不是更舒服,更簡(jiǎn)潔。
3. 降低了渲染效率
來(lái)個(gè)例子考考大家(以后我面試別人可能就會(huì)考這題),HTML如下:
現(xiàn)在要給這里的ul標(biāo)簽一個(gè)樣式,比如說(shuō)padding-left:25px;那么下面四種寫法哪個(gè)渲染速度最快?
#test .test{}, ul.test{},#test ul{} 以及.test{}。
如果單純的ul與.test PK,我還真拿不定誰(shuí)的渲染速度更快些。但是,一旦牽扯到層級(jí)與標(biāo)簽,我100%確定,.test這種最直接的命名方式渲染效率是最高的。要知道,CSS渲染元素和使用JavaScript獲取頁(yè)面元素那是完全不一樣的。如果是使用JavaScript獲取DOM元素,則#test ul{}速度是最快的,先id獲取,再tag獲取,這些可都是JavaScript內(nèi)置的方法。但是,CSS的渲染方式則是屬于外太空系的了,《高性能網(wǎng)站進(jìn)階指南》一書曾提到CSS的渲染方式是“從右往左”渲染的,就拿#test ul{}舉例,先渲染頁(yè)面上所有的ul標(biāo)簽,再去尋找id為test的元素,所以,出現(xiàn)#test div{}這種寫法的人都是傻×的,頁(yè)面先渲染id為test的元素?非也!先渲染頁(yè)面上所有的div,再去尋找其老爸有沒有id為test的元素。由于這種渲染差異最大就200~300毫秒(補(bǔ)充:這里的差異不是說(shuō)單純一個(gè)樣式的差異,而是這些寫法泛濫的頁(yè)面的全部渲染,其渲染差異數(shù)據(jù)可以參見“翻譯-不同CSS技術(shù)及其CSS性能”一文),我們?nèi)艘话闶歉杏X不到的。所以,長(zhǎng)久以來(lái),也都不以為然。但是,我是絕對(duì)容不下這種寫法的,還有,要是讓我看到類似于ul#test{}這樣子的命名,不好意思,面試肯定過(guò)不了。
所以,CSS命名,只要出現(xiàn)了層級(jí),出現(xiàn)了標(biāo)簽,就是一次額外的渲染,層級(jí)越多,渲染的開銷也就越大,這就是為什么一些前輩的文章會(huì)建議要盡量避免過(guò)深的層級(jí)。這也是為什么要“無(wú)層級(jí)”,“無(wú)標(biāo)簽”。
對(duì)于原則第一條“無(wú)ID”,其實(shí)與性能沒有多大關(guān)系,只是一般ID都與JavaScript有奸情,如果再牽扯到CSS樣式,如此復(fù)雜的三角關(guān)系,日后不好處理啊。
五、“三無(wú)原則”遺留之樣式?jīng)_突問(wèn)題
正如上面講的,層級(jí),標(biāo)簽可以避免樣式?jīng)_突,雖然“面向?qū)傩缘拿辈淮嬖跊_突問(wèn)題,但是,頁(yè)面上很多樣式是無(wú)法分離使用“面向?qū)傩缘拿钡?#xff0c;此時(shí),一不能有層級(jí),二不能有標(biāo)簽,如果避免沖突呢?
首先,規(guī)范。項(xiàng)目組所有人的命名方法,習(xí)慣都要統(tǒng)一。其次,也是實(shí)際的做法,同一內(nèi)容,使用同一前綴。就如上面的那張圖片所示,所有class同一使用od前綴,這樣,就絕不會(huì)與其他頁(yè)面的CSS產(chǎn)生沖突了。
現(xiàn)在,還隱藏著一個(gè)會(huì)讓人心存疑惑的遺留問(wèn)題。如下:
上圖中,很多個(gè)鏈接全部存放在一個(gè)標(biāo)簽中,全部都是a標(biāo)簽,按照我的“三無(wú)原則”,不能使用層級(jí),那么,我這里的每個(gè)a標(biāo)簽都得附一個(gè).index_list_a{}這樣子的命名嗎,這樣子repeat下來(lái),頁(yè)面HTML代碼豈不是很大,直接來(lái)個(gè).index_list_box a{},豈不是頁(yè)面HTML更加清爽。確實(shí)有理。實(shí)際上,按照我個(gè)人實(shí)踐的經(jīng)驗(yàn),這類細(xì)小重復(fù)的列表元素的樣式都是比較簡(jiǎn)單的,不要忘了,精簡(jiǎn)高效的CSS命名準(zhǔn)則之一的“分離與面向?qū)傩悦?#xff0c;所以,對(duì)這里的a標(biāo)簽進(jìn)行面向?qū)傩缘拿?#xff0c;權(quán)衡后期的重用性和HTML代碼開銷,還是直接針對(duì)a標(biāo)簽進(jìn)行簡(jiǎn)單命名是最佳解決方案。
但是,不排除這類最內(nèi)層標(biāo)簽且重復(fù)元素的樣式會(huì)很復(fù)雜,此時(shí),使用層級(jí)與標(biāo)簽,或許是更好的做法,但這只存在于一些非常特殊的情況。對(duì)了,我們看看點(diǎn)評(píng)網(wǎng)是如何對(duì)最內(nèi)層且重復(fù)的a標(biāo)簽進(jìn)行處理的,如下圖:
點(diǎn)評(píng)網(wǎng)是使用的一個(gè)大寫的”B”作為此樣式,無(wú)論這里的”B”是有background之意,還是邪惡的***之意,其命名比“面向?qū)傩悦备跻换I,可以說(shuō)是接近真正意義上的nothing,后面可以跟任意屬性,用在任意頁(yè)面,這就是“無(wú)”哲學(xué),“無(wú)”的境界。//zxx:點(diǎn)評(píng)網(wǎng)的這個(gè)命名讓我聞到了一點(diǎn)Google的氣息
六、結(jié)語(yǔ)
現(xiàn)在,來(lái)個(gè)簡(jiǎn)短的總結(jié),精簡(jiǎn)高效的CSS命名的關(guān)鍵字有“分離”,“統(tǒng)一前綴”,方法為“面向?qū)傩缘拿?#xff0c;準(zhǔn)則為“無(wú)層級(jí)、無(wú)標(biāo)簽”。其中,“分離”是“面向?qū)傩悦钡幕A(chǔ)。“面向?qū)傩悦焙汀盁o(wú)層級(jí)、無(wú)標(biāo)簽”屬于兩個(gè)不同的系列,一個(gè)針對(duì)短命名屬性,一個(gè)針對(duì)長(zhǎng)命名屬性。但是,兩個(gè)又互相依存。沒有“面向?qū)傩悦?#xff0c;“無(wú)層級(jí)、無(wú)標(biāo)簽”命名最后是以不堪重負(fù),HTML膨脹致死結(jié)局。而僅僅是“面向?qū)傩悦?#xff0c;前端開發(fā)人員會(huì)因維護(hù)過(guò)勞噴血而死。總之,兩者缺一不可。
上述所有內(nèi)容,都是根據(jù)自己的開發(fā)總結(jié)出來(lái)的東西,個(gè)人觀點(diǎn),經(jīng)驗(yàn)之談。每個(gè)人的成長(zhǎng)不同,工作環(huán)境不同,必然在看到一些問(wèn)題上會(huì)有差異,歡迎交流與討論。我資歷尚淺,文中難免會(huì)有不準(zhǔn)確的地方,歡迎指正。
我的這套準(zhǔn)則是建立在自己的一套CSS架構(gòu)上的,我自己用的是非常開心的,而且效果非常明顯。但是,到底是否適用于其他同行,我不能保證,畢竟優(yōu)秀的前端人員心中都有自己的那一套準(zhǔn)則。我的個(gè)人建議是這樣的,如果您還是個(gè)CSS新手,或者對(duì)我文中提到的一些概念不太理解,我覺得全搬過(guò)來(lái)不太合適。您可以保留您之前那種一步一趨的寫法,然后在這基礎(chǔ)上做您確定的改進(jìn)。如果真能對(duì)您CSS的學(xué)習(xí)提供一些幫助與啟示,那真是再好不過(guò)了。
補(bǔ)充于2013-01-10
今天我看到一篇譯文,復(fù)雜應(yīng)用的 CSS 性能分析和優(yōu)化建議,原文地址:http://perfectionkills.com/profiling-css-for-fun-and-profit-optimization-notes/
其中提供了很好的證據(jù)說(shuō)明,糟糕的命名對(duì)渲染性能造成的影響。
這是其中的測(cè)試圖:
可以看到,渲染性能最高的選擇器就是 .xxx a 這種形式是最好時(shí)的。這說(shuō)明,“類名+標(biāo)簽名”這種形式確實(shí)耗性能。本文可能戳中了不少自封人士的敏感神經(jīng),N多不屑,覺得這性能影響不值一提。OK,數(shù)據(jù)說(shuō)話,以下為一段引用:
其實(shí)并不存在最快的規(guī)則,我們通常做法是把樣式模塊合并到一個(gè)文件中試用,這樣會(huì)導(dǎo)致其中的一部分樣式并沒有被特定的頁(yè)面用到。其實(shí)把沒用的樣式規(guī)則拿掉是優(yōu)化 CSS 的最好的方法之一,因?yàn)檫@樣的話就可以省去多余的樣式匹配,當(dāng)然合并多個(gè)文件到一個(gè)大文件還是有好處的,比如說(shuō)可以減少請(qǐng)求數(shù),但是我們應(yīng)該只把跟當(dāng)前頁(yè)面有關(guān)的樣式打包到一起。
其實(shí)這也不算什么新發(fā)現(xiàn)了,Page Speed 早就有過(guò)這條建議。不過(guò),我還被它的效果嚇到了,去掉多余樣式讓我節(jié)省了大約?200-300ms?的選擇器匹配時(shí)間(根據(jù)Opera 調(diào)試工具的結(jié)果)。
200-300毫秒?你唬我吧!人家kangax大神可不會(huì)玩虛的~
很多網(wǎng)站CSS模塊都組隊(duì)放在一個(gè)CSS文件中,比方說(shuō)你有10個(gè)CSS模塊,每個(gè)模塊都有一個(gè).module_a a{} .module_b a{} ...的CSS命名,然后你訪問(wèn)只有模塊C的頁(yè)面,結(jié)果如何?不要天真地以為這個(gè)頁(yè)面不管模塊a和模塊b的事情。正如文中所說(shuō)的,CSS從右往左渲染,你的頁(yè)面是沒有.module_a?也沒有.module_b,到時(shí)你頁(yè)面有a標(biāo)簽啊,a標(biāo)簽大大的多哈!
于是,
.module_a a{}的時(shí)候,頁(yè)面上,所有的a標(biāo)簽掃一遍;
.module_b a{}的時(shí)候,頁(yè)面上,所有的a標(biāo)簽掃一遍;
.module_b c{}的時(shí)候,頁(yè)面上,所有的a標(biāo)簽掃一遍,恩,這個(gè)有效果;
.module_b d{}的時(shí)候,頁(yè)面上,所有的a標(biāo)簽掃一遍;
.
.
.
掃一遍只要0.3毫秒(如上截圖),你頁(yè)面要是有100個(gè)類似.xxx a{},那就是300毫秒的渲染,如果你現(xiàn)在還說(shuō)“300毫秒的渲染差異我不在意”的話,我也不能說(shuō)什么了!
原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明來(lái)自張?chǎng)涡?鑫空間-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=1098
轉(zhuǎn)載于:https://www.cnblogs.com/wxiaona/p/5757537.html
總結(jié)
以上是生活随笔為你收集整理的[css] 【转载】 精简高效的CSS命名准则/方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: m40数据导出
- 下一篇: 精简高效的CSS命名准则和方法