在大型專案中組織CSS
轉自:http://www.zcfy.cc/article/1202 (譯者:kayson)
編寫CSS容易。
編寫可維護的CSS難。
這句話你之前可能聽過100次了。
原因是CSS中的一切都預設為全域性的。如果你是一個C程式設計師你就知道全域性變數不好。如果你是任何一種程式設計師,你都知道隔離和可組合的模組是構建可維護系統的關鍵。
為了試圖幫助人們構建可維護的CSS,已經有很多CSS指南了:SMACSS, OOCSS, BEM, ITCSS, ACSS, CCSS,Atomic Design, Maintanable CSS, rscss, 並且可能還有 更多.
那麼,CSS的問題是什麼?
span {
font-size:11px;
}
.header-right {
font-size:22px;
text-align: right;
}
用一個如上的CSS定義,樣式立馬變成全域性的,它會影響所有應用樣式的頁面。沒有封裝。沒有隔離的模組。
在一個標準的程式語言裡,你只會為了要實現的特定功能引入一些模組,例如:
# Python modules
import requests
fromFlaskimport url_for
// Node modules
var express =require(‘express’)
這樣,你準確地知道什麼會影響你的程式碼,並且只有你顯式引入的內容才會影響到你當前正在實現的功能。
而在CSS中是反過來的。我每寫一行CSS程式碼,可能會影響到專案裡的所有部分,並且會無意間改變其他頁面的外觀。我的樣式不僅僅是洩露;它們蜂擁而出,遍佈應用程式的每個角落。
對基本的樣式設定如印刷格式,只是設定輸入欄位的樣式,或者本來就是全域性的樣式來說,這是可以理解的,也是合乎情理的。基本上HTML和CSS就是為此而生的。這些工具是為出版物製作的。為了理解這些語言背後的思想,我經常設想在給書排版:你不會想讓每一頁看起來都不一樣——是的,你想要簡單一致的樣式貫穿整本書,沒有太多垃圾。這就是為什麼像s之類的標籤是合理的,並且樣式是全域性的,會一直存在。
然而,世界變了,web也變了。我們不再製作網頁——我們構建web應用程式。HTML和CSS為之建立的出版物隱喻,不再適用於當今建立在web之上的大部分事物。
這確實需要一種 指定樣式的新方式,也許還要一種構建web的新方式。但是就目前來說,我們還無法擺脫CSS和HTML,這意味著我們不得不用一種產出可管理和可維護的應用程式的方式小心地使用這些工具。
Peergrade.io 處理CSS的方式
法則一:(給類名)加上字首
在Peergrade.io我們在所有類名中用了字首 .pg 。在CSS程式碼庫裡不使用字首是自找麻煩。原因就是不加字首的類名最終將會跟引入的樣式衝突。假設你需要一個datepicker ——你肯定不願意從頭開發一個(至少我不願意),因此你引入了一個。現在你的樣式裡到處都是.prev, .next, 和 .separator這樣的類名,可能會跟你自己的類名衝突——如果你不加字首的話。
很長一段時間 Font Awesome沒有在他們的類名上加字首,這意味著你經常跟他們的.icon-* 類名發生衝突(他們現在用了字首 .fa)。我們也難過地發現 Bootstrap 也沒有選擇加字首——但我們依然 ❤ 你, Mark Otto。
法則二:避免使用CSS選擇器巢狀
在Peergrade.io我們使用 Sass。使用 Sass 你很快進入一種Sass結構跟HTML結構相匹配的模式,例如:
#user-profile-page
.profile-description
h3
ul
li
a
這麼做之後你會發現,儘管感覺不錯,但它非常脆弱。在你寫它的時候你可能認為在.profile-description裡只會有一個列表,但一兩個月後你發現不得不需要另外一個列表,頁面結構很快超出你的設想。
並且,像這樣的樣式定義會應用到父元素內部的任何元素上——而不僅僅是你寫在Sass裡的那個層級。
對CSS選擇器巢狀你所做的是用 微妙 和 脆弱的方式繫結CSS和HTML結構。
法則三:採用BEM命名來開發元件
在構建可隔離元件時,儘可能採用BEM命名方案給類命名。我們沒有遵循完整的BEM指南——只是命名方案,這就是說類名應該是這種形式:
.block__element--modifier
為此我們這樣組織我們的 Sass:
.pg-deadline
&__date
// becomes `.pg-deadline__date`
color: $color-gray
&__header
// becomes `.pg-deadline__header`
font-weight:700
&--highlight
// becomes `.pg-deadline__header--highlight`
color: $color-green
這裡你看到的是我們用Sass巢狀為我們建立BEM類名。有點反直覺的是,這會產生完全扁平的css結構——沒有巢狀——只有頂層的類名定義。
作為法則二的一個例外,我們允許 .block–modifier 形式的類名。
.pg-deadline--editable
.pg-deadline__header
background-color: $color-blue
.pg-deadline__date
color: $color-black
在這個特殊的例子中,我們允許 1層CSS選擇器巢狀。這就允許我們只要指定區塊的修飾符——也就是正在編輯的內容—— 不用在區塊內的所有子元素上重複修飾符(BEM中的E)。
為了更好地理解類似BEM的命名方式,前往檢視Harry Roberts的CSS指南的類BEM命名部分。(需要提到的是,我們發現Harry實際上建立了一套跟我們類似的命名方案。)
展望
似乎還沒有人真正找到處理CSS的最佳方式,看著Hack News上精選的這篇文章,我對CSS的現狀多少有點失望,本來我們可以做得更好。
結論就是:我們相信已經找到了CSS的可持續基礎——當然還有改進的空間。這個計劃就是經常對照檢查我們的指南,看看事情是不是朝我們預期的方向發展,並且在必要的時候修訂。
END