❶ css的書寫規范,有哪些注意點
一、「無」的哲學
佛家講究「因果報應」,有果必有應。此段看似與主題沒有血緣關系,實際講的是「因」。
我個人比較喜歡老子的道家思想,並喜歡以其思想解釋學習與工作中遇到的一些問題。例如我之前寫過的「中國古代道家思想與網頁重構的思考」一文。
老子有雲:「天下萬物生於有,有生於無」。具體解釋就是:天下萬物都是由看得見的具體事物(「有」)產生的,而看得見的具體事物(「有」)又是由看不見的,無形無狀的東西(「無」)產生的,這個看不見的「無」也就是「道」,或叫做「根」、「母」。
我們看武俠片,經常聽到「無招勝有招」這句話,這也是道家「無」之思想之體現。因為你心中沒有招式,你才能有無限的可能,生成其他的招式以克敵,即所謂以不變應萬變;相反,如果你心中牢記一套「華山劍法」,當你與人交手時,勢必按照此套路走,要是遇到相剋之劍法,結局就是一敗塗地。「無招」是一種境界,是你功夫修煉到一定程度才能領悟到的。我們這代人應該都看過李連傑主演的《倚天屠龍記魔教教主》,其中張三豐老頭教完張無忌太極拳後問他「記住了沒?」張無忌一句「全忘記了!」讓人印象深刻。這就是「無」的境界。
這種境界我是深有體會的。例如每逢大考之前,我總是把以前做過的題目全部忘掉,這樣,考試時就能思如泉湧;反而是強記題目的做法限制了發揮。這就好比發射炮彈,炮管里提前預裝了重型炸蛋,結果戰斗開始時,發現需要的是煙霧彈,此時,反而被預裝的炸蛋給阻塞限制了。打籃球也有這種體會,如果心中記得的是動作,我要這么走,然後這么做,往往表現不佳。反而是腦中什麼想法也沒有,全靠下意識行動,那真是所向披靡,得分如探囊取物。
可見,要想發揮更大,就需要「無」,把一些「限制的東西」通通去掉。沒有限制才能發揮出最大的潛能。站在最簡單,最原始的那個點上,你才能自由馳騁,應變自如。
二、名字的本質是什麼
我們有沒有思考過這么一個問題:名字的本質是什麼?
這個問題其實不難,名字本質上就是一個符號,用來區分人與人的。與符號一樣,名字本身就蘊含著很多的信息。舉個例子,我的名字:張鑫旭。其中蘊含的信息有:我老爸也姓張,我是上午太陽剛剛升起的時候出生的,我五行缺金。一個名字,如果其蘊含的信息越多,則這個名字就越獨特,也就是說,越不可能被別人使用;相反如果這個名字很普通,例如李娜、張艷之類,就會被大規模的重用,OK,這其實沒什麼大不了的,我們的唯一身份標識不是名字,而是身份證,但是,對於CSS樣式的命名,沖突與否可不是拉便便,擦個屁股就沒事的。
對於CSS,為了避免樣式沖突,我們總會給其賦予相當特殊的命名,或是在選擇符上添加HTML標記,或是使用層級。所謂一朝怕蛇咬,十年怕井繩。一旦我們經歷過樣式沖突帶來的讓人吐血的麻煩後,我們可能就會時時在避免沖突上狠做文章,所謂過猶不及,結果又是一個爛攤子,本如花似玉的黃花小閨女變成個臃腫的肥妞。例如下面人人網的CSS命名:
我想我們都希望寫出精簡高效的CSS代碼,如果CSS重用性越高,想必就越高效。這如人的名字一樣,如果名字越普通,越沒有含義,越容易被重用,所以CSS要想重用性高,就需要命名簡單。但是,簡單的命名越容易造成樣式沖突,例如.more{}。從這點上來說,重用性與樣式沖突時兩個對立的矛盾體。
不過,萬幸的是,這種矛盾並不是不可調和的。記住一些准則/方法,CSS既可以有高度的重用性,又不會有樣式沖突的困擾。下面就將介紹這些命名方法。
三、面向屬性的命名方法
我們習慣在CSS命名的時候摻雜語義,這樣可以讓代碼更易懂。例如淘寶首頁「免費注冊」按鈕上的class名稱:help-guest-regist
上面的class命名語義就很明顯,獨眼龍看告示——一目瞭然,」help-guest-regist」就是」幫助-顧客-注冊」,很nice,很人性化的命名。作為在單一的首頁上使用,我是很難挑出什麼毛病來的。
但是,從道家「無」的哲學思想來看,語義其實是對自身的一種束縛,越是語義強烈的命名越是沒有重用性(尤其是內容語義的)。舉個實際點的例子,例如人人網的右側邊欄的標題://zxx:一般找這類反例我就喜歡找人人網還有新浪,基本上一找一個准。人人網雖然外表長得跟facebook類似,但是就CSS而言,差距不是一兩個檔次的。
這個標題的class名是」side-item-header」,樣式如下圖所示:
現在一切ok,現在設想下,如果頁面中間的模塊有個標題,其樣式也是:
{padding:0 0 8px; text-align:right;}
那你發現前面已經有一模一樣的CSS樣式後,你會怎麼辦。把中間的標題也用」side-item-header」這個class嗎?這里」side」就是表示「邊」的意思,這就意味著這個樣式用在非側邊欄就是不合理的。你能做的估計即使新命名一個class,就像是」body-item-header」,明明是同樣的CSS屬性,結果卻不能重用(即使使用標識符組合並CSS,這里的命名也是沒有重用的)。
可見命名不合理會大大限制你的CSS重用性。如何命名才能讓CSS發揮最大的重用性潛力呢?答案就是「面向屬性的命名」。這種命名就是要讓你把頁面啊設計啊什麼的通通塞到馬桶里沖走,不要管頁面什麼位置,什麼內容,there is noting, 這兒什麼都沒有,既然什麼都沒有,也就沒有了任何限制,於是CSS可以自由出入於任何地方,無限重用,而且不用擔心沖突,因為「面向屬性的命名」就是針對自身屬性的一種命名方式,只會overwrite,不會沖突。
相比很多同行都用過這樣的命名方式,只是不夠系統,不夠大膽、徹底,多淺嘗輒止,比如像是開心網,還有時光網的CSS代碼的前面一部分樣式命名:
我在「CSS樣式分離之再分離」一文中就展示過這種命名了,分離為什麼可以讓樣式的重用性放大至最大,就是因為分離後樣式的命名就是樣式本身。
就拿上面人人網的標題樣式舉例,人人網的做法是:
.side-item-header{padding:0 0 8px; text-align:right;}
要是我,我會對其進行分離。在實際項目時,text-align:right;這個屬性早就在CSS通用樣式庫裡面了,而padding:0 0 8px;則會以padding-bottom:8px;的形式放在網站通用樣式庫里了(詳細請參見我的「我是如何對網站CSS進行架構的」一文)。最後,CSS命名與樣式會如下:
.tr{text-align:right;}
.pb8{padding-bottom:8px;}
而這里分離出來的樣式又可以被其他地方使用。是不是有點「吸星大法」的感覺。
當然,如果網站本身的架構不是對每個側欄內容進行模塊化處理的話,說實話,這里標題的分離還是有點危險的。想想看,如果那天產品經理說底部padding值要改成10像素,啊哦,如果你的網站架構不合理,含這類標題的模塊到處塞,會改到你急火攻心,吐血三升而亡的。所以,對於分離,我反復強調,「千萬不要對網站通用的元素進行分離」。
所以,記住精簡高效的CSS命名准則之一:對於網站非通用元素,如果樣式簡單(1~2個屬性),對其分離並使用面向屬性的命名方法。
四、精簡高效CSS命名之「三無原則」
此「三無原則」就是:無ID,無層級,無標簽
CSS命名就應該最簡單、最直接,直搗黃龍。沒有HTML標簽,沒有層級,這些通通滾蛋,不要。為什麼不要,有三大原因:
1. 限制重用
我們會使用層級(#test .test),會使用標簽(ul.test),可能是習慣(沒多想),或是為了避免沖突。但是,我跟你說,從今以後,這種寫法讓他見鬼去吧(如果不是為了改變CSS優先順序的話)。正如開篇論述的哲學觀點,你限制越多,越抑制了CSS的重用性。例如#test .test{}這種寫法,裡面的CSS重用性多大,完全限死在了id為test的元素下,哪有重用性可言;又如ul.test,我勒個去,這個ul標簽十有八九就是裝飾用的,往這兒一放,同樣CSS樣式的div標簽可以用嗎?哭爹喊娘,眼淚汪汪也不管用啊。所以,相信我,層級啊,標簽啊什麼的,通通見鬼去吧。要知道,層級啊,標簽啊作用是什麼,是用來提高CSS優先順序,把那個字母長的讓人發毛的」!important」幹掉的。
2. CSS文件大小
這瓜子雖小,吃多了也是可以填飽肚子的。所以,你的CSS名稱不要像老太太的裹腳布一樣,搞得又臭又長,如下圖所示的人人網那個冗長的CSS命名吧:
你看名稱的位元組數已經比屬性還大了,要是這些名稱都在15字元以內,乖乖,這個CSS文件可以小個1~2K絕對沒有問題的。你看下圖這樣子的命名,這樣子的CSS排版是不是更舒服,更簡潔。
3. 降低了渲染效率
來個例子考考大家(以後我面試別人可能就會考這題),HTML如下:
<div id="test">
<ul class="test"></ul>
</div>
現在要給這里的ul標簽一個樣式,比如說padding-left:25px;那麼下面四種寫法哪個渲染速度最快?
#test .test{}, ul.test{},#test ul{} 以及.test{}。
如果單純的ul與.test PK,我還真拿不定誰的渲染速度更快些。但是,一旦牽扯到層級與標簽,我100%確定,.test這種最直接的命名方式渲染效率是最高的。要知道,CSS渲染元素和使用JavaScript獲取頁面元素那是完全不一樣的。如果是使用JavaScript獲取DOM元素,則#test ul{}速度是最快的,先id獲取,再tag獲取,這些可都是JavaScript內置的方法。但是,CSS的渲染方式則是屬於外太空系的了,《高性能網站進階指南》一書曾提到CSS的渲染方式是「從右往左」渲染的,就拿#test ul{}舉例,先渲染頁面上所有的ul標簽,再去尋找id為test的元素,所以,出現#test div{}這種寫法的人都是傻×的,頁面先渲染id為test的元素?非也!先渲染頁面上所有的div,再去尋找其老爸有沒有id為test的元素。由於這種渲染差異最大就200~300毫秒(補充:這里的差異不是說單純一個樣式的差異,而是這些寫法泛濫的頁面的全部渲染,其渲染差異數據可以參見「翻譯-不同CSS技術及其CSS性能」一文),我們人一般是感覺不到的。所以,長久以來,也都不以為然。但是,我是絕對容不下這種寫法的,還有,要是讓我看到類似於ul#test{}這樣子的命名,不好意思,面試肯定過不了。
所以,CSS命名,只要出現了層級,出現了標簽,就是一次額外的渲染,層級越多,渲染的開銷也就越大,這就是為什麼一些前輩的文章會建議要盡量避免過深的層級。這也是為什麼要「無層級」,「無標簽」。
對於原則第一條「無ID」,其實與性能沒有多大關系,只是一般ID都與JavaScript有姦情,如果再牽扯到CSS樣式,如此復雜的三角關系,日後不好處理啊。
五、「三無原則」遺留之樣式沖突問題
正如上面講的,層級,標簽可以避免樣式沖突,雖然「面向屬性的命名」不存在沖突問題,但是,頁面上很多樣式是無法分離使用「面向屬性的命名」的,此時,一不能有層級,二不能有標簽,如果避免沖突呢?
首先,規范。項目組所有人的命名方法,習慣都要統一。其次,也是實際的做法,同一內容,使用同一前綴。就如上面的那張圖片所示,所有class同一使用od前綴,這樣,就絕不會與其他頁面的CSS產生沖突了。
現在,還隱藏著一個會讓人心存疑惑的遺留問題。如下:
上圖中,很多個鏈接全部存放在一個標簽中,全部都是a標簽,按照我的「三無原則」,不能使用層級,那麼,我這里的每個a標簽都得附一個.index_list_a{}這樣子的命名嗎,這樣子repeat下來,頁面HTML代碼豈不是很大,直接來個.index_list_box a{},豈不是頁面HTML更加清爽。確實有理。實際上,按照我個人實踐的經驗,這類細小重復的列表元素的樣式都是比較簡單的,不要忘了,精簡高效的CSS命名准則之一的「分離與面向屬性命名」,所以,對這里的a標簽進行面向屬性的命名,權衡後期的重用性和HTML代碼開銷,還是直接針對a標簽進行簡單命名是最佳解決方案。
但是,不排除這類最內層標簽且重復元素的樣式會很復雜,此時,使用層級與標簽,或許是更好的做法,但這只存在於一些非常特殊的情況。對了,我們看看點評網是如何對最內層且重復的a標簽進行處理的,如下圖:
點評網是使用的一個大寫的」B」作為此樣式,無論這里的」B」是有background之意,還是邪惡的***之意,其命名比「面向屬性命名」更甚一籌,可以說是接近真正意義上的nothing,後面可以跟任意屬性,用在任意頁面,這就是「無」哲學,「無」的境界。//zxx:點評網的這個命名讓我聞到了一點Google的氣息
六、結語
現在,來個簡短的總結,精簡高效的CSS命名的關鍵字有「分離」,「統一前綴」,方法為「面向屬性的命名」,准則為「無層級、無標簽」。其中,「分離」是「面向屬性命名」的基礎。「面向屬性命名」和「無層級、無標簽」屬於兩個不同的系列,一個針對短命名屬性,一個針對長命名屬性。但是,兩個又互相依存。沒有「面向屬性命名」,「無層級、無標簽」命名最後是以不堪重負,HTML膨脹致死結局。而僅僅是「面向屬性命名」,前端開發人員會因維護過勞噴血而死。總之,兩者缺一不可。
上述所有內容,都是根據自己的開發總結出來的東西,個人觀點,經驗之談。每個人的成長不同,工作環境不同,必然在看到一些問題上會有差異,歡迎交流與討論。我資歷尚淺,文中難免會有不準確的地方,歡迎指正。
我的這套准則是建立在自己的一套CSS架構上的,我自己用的是非常開心的,而且效果非常明顯。但是,到底是否適用於其他同行,我不能保證,畢竟優秀的前端人員心中都有自己的那一套准則。我的個人建議是這樣的,如果您還是個CSS新手,或者對我文中提到的一些概念不太理解,我覺得全搬過來不太合適。您可以保留您之前那種一步一趨的寫法,然後在這基礎上做您確定的改進。如果真能對您CSS的學習提供一些幫助與啟示,那真是再好不過了。
其中提供了很好的證據說明,糟糕的命名對渲染性能造成的影響。
這是其中的測試圖:
可以看到,渲染性能最高的選擇器就是 .xxx a 這種形式是最好時的。這說明,「類名+標簽名」這種形式確實耗性能。本文可能戳中了不少自封人士的敏感神經,N多不屑,覺得這性能影響不值一提。OK,數據說話,以下為一段引用:
其實並不存在最快的規則,我們通常做法是把樣式模塊合並到一個文件中試用,這樣會導致其中的一部分樣式並沒有被特定的頁面用到。其實把沒用的樣式規則拿掉是優化 CSS 的最好的方法之一,因為這樣的話就可以省去多餘的樣式匹配,當然合並多個文件到一個大文件還是有好處的,比如說可以減少請求數,但是我們應該只把跟當前頁面有關的樣式打包到一起。
其實這也不算什麼新發現了,Page Speed 早就有過這條建議。不過,我還被它的效果嚇到了,去掉多餘樣式讓我節省了大約 200-300ms的選擇器匹配時間(根據Opera 調試工具的結果)。
200-300毫秒?你唬我吧!人家kangax大神可不會玩虛的~
很多網站CSS模塊都組隊放在一個CSS文件中,比方說你有10個CSS模塊,每個模塊都有一個.mole_a a{} .mole_b a{} ...的CSS命名,然後你訪問只有模塊C的頁面,結果如何?不要天真地以為這個頁面不管模塊a和模塊b的事情。正如文中所說的,CSS從右往左渲染,你的頁面是沒有.mole_a 也沒有.mole_b,到時你頁面有a標簽啊,a標簽大大的多哈!
於是,
.mole_a a{}的時候,頁面上,所有的a標簽掃一遍;
.mole_b a{}的時候,頁面上,所有的a標簽掃一遍;
.mole_b c{}的時候,頁面上,所有的a標簽掃一遍,恩,這個有效果;
.mole_b d{}的時候,頁面上,所有的a標簽掃一遍;
❷ 起什麼名字
張靜宸 宸:古代君王的代稱
張詩琪 (詩情畫意;美玉)
張美萱 萱:一種忘憂的草
張雪雁 (在雪花中飛舞的飛雁)
天瑜 瑜:美玉
張婧琪 婧:女子有才 琪:美玉
張夢瑤 瑤:美玉