在CSS中,我們都知道所有代碼都在一個“根級別”的選擇器中,每個CSS的樣式聲明都寫嵌套的話,那意客味需要寫很多的代碼。
今天我要帶領大家進入到Sass的最基本原則中。這就是所謂的“基礎規則(Inception rule)”。此規則可以幫助你避免一些常見錯誤(使用Sass的常見錯誤),不管是你Sass的初學者,還是中級或者高級Sass開發者。
就拿下面的代碼為例:
.post { border-radius: 3px; background: #FFF8FF; border: 1px solid #EFC6F3; padding: 15px; color: #333333; } .post .title, .post .alt-title { color: #000000; font-size:20px; } .post .alt-title { border-bottom:1px solid #EFC6F3; }
奇怪的是,你在使用CSS的時候,一旦你被卡住的時候,你會考慮加載其它的類名,如此一來,你的HTML就看不到明於,你是否在你的結構中同時加過五個類名呢?
<div class="post complete highlight rounded clearfix">...</div>
這難道就是你日常生活中所說的,面包和奶油我都要嗎?其實我認為這樣讓我無法享受CSS開發的樂趣。然而,只要Sass進入你的生活中,你會發現這樣使用CSS太過時了。
結合Sass使用很容易,但也很容易的錯誤使用它。
當你在工作中開始使用Sass的時候,第一個讓你喜歡的特性就是“選擇器嵌套”。如果能根據選擇嵌套讓你節省少敲鍵盤等事情,這將是一個很奇特事情。
我們來的看下面的一個示例,這就是Sass中的選擇器的嵌套:
$border: 1px solid #EFC6F3; .post { border-radius: 3px; background: #FFF8FF; border: 1px solid $border; padding: 15px; color: #333333; .title { color: #000000; font-size:20px; } .alt-title { @extend .title; border-bottom:1px solid $border; } }
上面的代碼會輸出相同的CSS。下面的代碼就是Sass編譯出來的CSS,所以你可以看看是如何轉換成CSS的。
.post { border-radius: 3px; background: #FFF8FF; border: 1px solid 1px solid #efc6f3; padding: 15px; color: #333333; } .post .title, .post .alt-title { color: #000000; font-size: 20px; } .post .alt-title { border-bottom: 1px solid 1px solid #efc6f3; }
所以這些就像孩子玩他的玩具一樣,我們開始使用他們的功能,認為是他們的“最大潛力”。但實際情況是什么時候應該這樣調用,這又將是CSS選擇器的一個噩夢。
CSS選擇器的噩夢
對於前端工程師來說,其噩夢就是樣式臃腫,而且下DOM緊密耦合在一起,你修改有關於結構的內容就會影響破壞前端的呈現。
讓我們來看一個不怎么好的HTML結構:
<body> <div class="container"> <div class="content"> <div class="articles"> <div class="post"> <div class="title"> <h1><a href="#">Hello World</a> </div> <div class="content"> <p></p> <ul> <li>...</li> </ul> </div> <div class="author"> <a href="#" class="display"><img src="..." /></a> <h4><a href="#">...</a></h4> <p> <a href="#">...</a> <ul> <li>...</li> </ul> </p> </div> </div> </div> </div> </div> </body>
因為Sass給你提供了這方面的功能,你可以讓你的選擇器嵌套在里面,你的代碼封裝在一起,避免了與其他樣式的沖突問題。你可能發現在Sass中的代碼類似於你的DOM結構的嵌套。(這是不好的一種想法)。
來看一段不合理的Sass代碼,類似不好的HTML的DOM結構:
body {
div.container {
div.content {
div.articles {
& > div.post {
div.title {
h1 {
a {
}
}
}
div.content {
p { ... }
ul {
li { ... }
}
}
div.author {
a.display {
img { ... }
}
h4 {
a { ... }
}
p {
a { ... }
}
ul {
li { ... }
}
}
}
}
}
}
}
這樣都好,對嗎?使用上面的選擇器,你百分之百的可以預測到什么時候會發生什么?沒有級聯可以擊敗選擇器的權重。
有關於CSS選擇器權重的相關知識,可以閱讀@99早前根據Vitaly Friedman的《CSS Specificity: Things You Should Know》所譯的文章《你應該知道的一些事情——CSS權重》,文章中詳細介紹了選擇器權重相關知識。——@大漠
Sass編譯之后,我們看到這樣的一個結果,你會發現我們創建了一個極差勁的CSS。唉!
body { ... }
body div.content div.container { ... }
body div.content div.container div.articles { ... }
body div.content div.container div.articles > div.post { ... }
body div.content div.container div.articles > div.post div.title { ... }
body div.content div.container div.articles > div.post div.title h1 { ... }
body div.content div.container div.articles > div.post div.title h1 a { ... }
body div.content div.container div.articles > div.post div.content { ... }
body div.content div.container div.articles > div.post div.content p { ... }
body div.content div.container div.articles > div.post div.content ul { ... }
body div.content div.container div.articles > div.post div.content ul li { ... }
body div.content div.container div.articles > div.post div.author { ... }
body div.content div.container div.articles > div.post div.author a.display { ... }
body div.content div.container div.articles > div.post div.author a.display img { ... }
body div.content div.container div.articles > div.post div.author h4 { ... }
body div.content div.container div.articles > div.post div.author h4 a { ... }
body div.content div.container div.articles > div.post div.author p { ... }
body div.content div.container div.articles > div.post div.author p a { ... }
body div.content div.container div.articles > div.post div.author ul { ... }
body div.content div.container div.articles > div.post div.author ul li { ... }
有很多原因可以證明,這完全是錯誤的,從渲染到文件的大小等都足以說明。試想想,這是加了多少的字節,文件大小直接受影響,或許你會保守的說:
嘿,電腦速度很快。互聯網下載速度也比較快!——用戶誰不喜歡前端工程師
但是,這並不是唯一的一個問題,你的樣式非常類似於DOM結構,可維護就變成一個問題。
你的結構做任何的修改都需要告訴Sass,反之也是如此。這也意味着,樣式和結構完全違背了“級聯”的部分宗旨。也就是所說的“層疊樣式表”。
如果你這樣寫,還不如回到當初的年代,把CSS直接寫到HTML的結構中。(請不要這樣做)。
滿足簡單規則
為了防止你陷入這樣的噩夢之中,我創建了一些簡單的規則。到現在為止,這個規則雖然還不成文,但還是有蠻多人跟着使用。
這個規則就是:不要讓你的嵌套層級超過四個層級。
這也就意味着你不需要一味的模仿DOM結構中的任何一點。如果你發現你的嵌套的層級憶超過四層,那這將是一個危險的信號。當然,有時候你為了需要,而不得不這樣做,但你不能像這樣做得太多。
讓嵌套在四層或更少層級內
一旦你理解選擇器的具體問題之后,你需要考慮的是如何讓你的代碼更通用,需要改善你的環境,對象和交互狀態等。
網站內容
如果你的結構沒有類名或ID,那么你至少需要一個標簽。很好的例子就是,像h1~h6,ul和p有一個默認的樣式。
有可能在一些環境下,你需要覆蓋一些樣式,這時你可能要增加幾個選擇器。當涉及到網站內容上下文時,使用具有一定特色的選擇。
頁面內容(布局、側邊欄寬度和高度)
如果你是寫布局的樣式(側邊欄和內容維度,也就是根據頁面上下內容元素而有所不同),那么你討論的將是在頁面中的上下文。通常你需要兩個級別的縮進來達到你需要的目的。但是請記住,你應該只指定樣式,而不是對象自身。下一節我們將討論對像。
下面的示例就是我想要說的意思:
.cart {
#sidebar { width: 150px; } #content { width: 850px; } }
對象
一個元素就是一個對象,他有可能就是自身,也有可能帶有子元素(或后代元素),通常使用一個類名或ID來定義這個對象。這也是你代碼中常見的一種類型。對象可以是任何東西,應該被當作一個整體傳到你的頁面中。你也可以將對象作為一個基本樣式,然后需要的時候使用頁面內容來修改他。
下面是常用的一些元素當對象使用的示例:
#sideabr #content #footer .blog-post .comment .widget .logo .user .button
你通常會設置一個頂層的類來識別對象,並將其做為一個基本的選擇器,在那你應該使用最普通的選擇器來寫樣式:
ul.special-deal {
...
li {...}
a {...}
}
請注意,對象最多只能是四層嵌套。大多數時候你只寫兩到三層嵌套,至少要留一個層級給交互。
交互狀態
當你與對象有交互狀態時,交互狀態會包括什么。當你有交互的時候,你的對象層級嵌套有可能接近或超過四層。這是預期的,並且是可以接受的。
切記
- 聰明:想想編譯器是如何創建你的代碼,並問自己,它生成的代碼是自己真正需要的CSS嗎?我總是問自己,這種風格還有更簡單的選擇器來實現?
- 靈巧:使用編譯器為你提供的一切。例如,使用
@extend指令或mixin。每一個都有其自身的意義。 - 記錄:如果添加一個聲明會影響你全局的HTML標簽,你應該留一個言,將其記錄下來。當數周或數月后,你再看你的代碼,你知道發生了什么。注釋是你很好的朋友,如果你要嵌套
article、aside、section和h3這樣的,你最好有一個很好的理由。 - 創意:有沒有一種方法,在沒有增加額外的類名能使HTML與CSS更好的一起工作呢?如果有,他不影響語義做到這一點。我的意思是使用相鄰選擇器或子選擇器等等來實現。只有知道你Sass中嵌套的層級才知道你的CSS規則。
- 適度:任何事情濫用都是不好的。有疑問時要用你的常識來判斷。
譯者手語:整個翻譯依照原文線路進行,並在翻譯過程略加了個人對技術的理解。如果翻譯有不對之處,還煩請同行朋友指點。謝謝!
如需轉載,煩請注明出處:
英文出處:http://thesassway.com/beginner/the-inception-rule
中文譯文:http://www.w3cplus.com/preprocessor/beginner/the-inception-rule.html
