許多開發者非常討厭 CSS,這導致了他們不願意花太多時間去學習 CSS。
雖然 CSS 不是一門好的“語言”,但 CSS 成功的為 Web 提供了20年的樣式支援,理論上不會太差。
當你在專案中寫了大量的 CSS 後,你會發現 CSS 的致命缺陷 -- 維護成本巨大。
加上糟糕的 CSS 命名,會讓你體會到被它支配的恐懼。
下面我將介紹幾種 CSS 命名規則,解救你於水火之中。
用連字元命名
在 JavaScript 中,我們喜歡用駝峰命名法。
var redBox = document.getElementById('...')
複製程式碼
但它並不適合 CSS。
建議不要這樣寫:
.redBox {
border: 1px solid red;
}
複製程式碼
最佳寫法:
.red-box {
border: 1px solid red;
}
複製程式碼
這是非常標準的 CSS 命名寫法,可讀性更好。
同樣的,CSS 屬性也要用連字元:
// Correct
.some-class {
font-weight: 10em
}
// Wrong
.some-class {
fontWeight: 10em
}
複製程式碼
BEM 命名規則
不同的團隊可能有不同的命名規則,有的團隊喜歡用連字元來命名,有的團隊喜歡用更結構化的命名規則 -- BEM 命名規則。
通常 CSS 命名需要解決三個問題:
- 通過名字就要知道它是幹什麼的。
- 通過名字就要知道它在哪裡被使用。
- 各個名字之間的關係。
你有沒有見過這樣的命名:
.nav--secondary {
...
}
.nav__header {
...
}
複製程式碼
這就是 BEM 命名規則。
如何向5歲小孩解釋 BEM
BEM 試圖將整個使用者介面劃分成各個可重用的小元件。
想象下下面這幅圖:
這個火柴人(stick-man)表示一個元件,類似於塊設計(block of design)。
你可能已經猜到,BEM 中的 B 指的就是 block。
在使用者介面中,‘block’ 指的就是 navigation,header,footer 等等。
所以對於這個元件,我們可以命名為 stick-man
。
.stick-man {
}
複製程式碼
我們使用連字元的命名。
E 表示元素(Element)
BEM 中的 E 表示元素。
整個塊設計中的元素很少有孤立存在的。
比如火柴人,擁有頭(head),手(arms),腳(feet)。
我們可以把 head,arms,feet 看成火柴人的子元件。
使用 BEM 命名規則,元素命名需要兩個下劃線:
.stick-man__head {
}
.stick-man__arms {
}
.stick-man__feet {
}
複製程式碼
M 表示可變部分(Modifiers)
BEM 中的 M 表示可變部分。
如果把火柴人修改成紅色或者藍色:
在真實的介面的中,比如紅色的按鈕或者藍色的按鈕,其中紅色和藍色是可變部分。
使用 BEM 命名規則,可變部分命名需要兩個連線符:
.stick-man--blue {
}
.stick-man--red {
}
複製程式碼
我們再看下面這個例子,有個不同大小頭部的火柴人:
.stick-man__head--small {
}
.stick-man__head--big {
}
複製程式碼
注意,雙連字元。
這是 BEM 基礎用法,進一步瞭解。
為什麼要使用命名規則
在電腦科學中只有兩個麻煩事:快取失效和命名 — Phil Karlton
命名很麻煩。所以我們要嘗試讓它變得簡單,減少以後維護程式碼的成本。
如果你用 BEM 命名規則,可以讓你通過名字就能輕易的分辨出你設計的元件。
用於 JavaScript 的 CSS 命名
我們先來看一段我專案中的 HTML 程式碼:
<div class="siteNavigation">
</div>
複製程式碼
通過上面的學習,我們來重構下這段 HTML:
<div class="site-navigation">
</div>
複製程式碼
gg,報錯了。
因為在 JavaScript 程式碼中有段這樣的程式碼:
//the Javasript code
const nav = document.querySelector('.siteNavigation')
複製程式碼
因為我們改變了 CSS 名稱導致了 JavaScript 程式碼報錯。
為了避免上述問題的發生,不同用途的 CSS,我們要採用不用的策略。
1.使用 js- 命名
用一個 js-* 命名來表示與 DOM 有關聯的名稱。
比如:
<div class="site-navigation js-site-navigation">
</div>
複製程式碼
JavaScript 中的程式碼:
//the Javasript code
const nav = document.querySelector('.js-site-navigation')
複製程式碼
任何看到 js-site-navigation
類名就會想到,這個名稱會用於 JavaScript 程式碼中。
2.使用 Rel 屬性
還是上面那個例子,我們也可以這樣寫:
<div class="site-navigation" rel="js-site-navigation">
</div>
複製程式碼
JavaScript 程式碼:
const nav = document.querySelector("[rel='js-site-navigation']")
複製程式碼
Web 開發最神奇的地方就是,同一個問題,你可以用多種方式去解決。
3.不要用來儲存資料
很多開發者喜歡在 DOM 上儲存自定義資料,最好別這樣用。如果必須要這樣,請參考 Twitter 的用法:
寫 CSS 註釋
這個部分和命名規範沒什麼關係,好的註釋也會方便你維護程式碼。
很多開發者不願意寫 CSS 註釋,或者寫的很少,我個人覺得註釋是很有必要的。
應為 CSS 並不是一門有沒的“語言”,所以好的註釋會幫助你理解程式碼。
怎麼寫 CSS 註釋呢?強烈推薦 Bootstrap 的原始碼。
最後
為大家推薦一本 CSS 進階的書。
感謝閱讀!
本文翻譯自 medium 上 Ohans Emmanuel 的 CSS Naming Conventions that Will Save You Hours of Debugging