前言
沒有太重視“命名”這個似乎不在技術範疇之內的東西,隨著專案更新迭代變得龐大,維護起來欲哭無淚。尤其是在CSS中,一個高效的命名規範到底有多重要?
- 程式碼結構更加清晰有意義
- 維護變得簡單
- 同事看程式碼的時候不罵街了
之前看到過一種醜醜的命名("__"和"--")不以為然,這正是本文探討的主題——BEM命名規範。
1. BEM簡介
BEM(Block Element Modifier)是由Yandex(俄羅斯的網路服務門戶之一)團隊提出的一種前端命名規範,這裡講的BEM風格是經過改良的(沒有具體閱讀過相關文章,不探討有關如何改良的細節):
- Block:塊
- Element:元素——塊的組成部分
- Modifier:修飾符——表示一種形態/狀態
.block {}
.block__element {}
.block--modifier
複製程式碼
舉一個很好理解的例子:
人 #Block
人__手 #Element
人__手--小手 #Modifier
人__手--大手 #Modifier
人__腳 #Element
人--男人 #Modifier
人--男人__手 #Element
人--男人__腳 #Element
人--女人 #Modifier
人--女人__手 #Element
人--女人__腳 #Element
複製程式碼
2. BEM命名 vs 傳統命名
好與不好,程式碼為證:
2.1 BEM命名
<!-- app.vue -->
<aside class="aside">
<!-- 顯示/隱藏側邊欄 -->
<img :class="['aside__toggle--show', {'aside__toggle--hide': isHide}]" />
<ul class="aside__menu">
<li class="aside__menu__item">首頁</li>
</ul>
</aside>
複製程式碼
/*css*/
.aside {}
.aside__toggle--show {}
.aside__toggle--hide {}
.aside__menu {}
.aside__menu__item {}
複製程式碼
/*scss或less*/
.aside {
&__toggle {
&--show {}
&--hide {}
}
&__menu {
&__item {}
}
}
複製程式碼
2.2 傳統命名
<!-- app.vue -->
<aside class="aside">
<!-- 顯示/隱藏側邊欄 -->
<img :class="['toggle', {'hide': isHide}]" />
<ul class="menu">
<li class="item">首頁</li>
</ul>
</aside>
複製程式碼
.aside {}
.toggle {}
.menu {}
.item {}
複製程式碼
當然也有一些針對傳統命名的優化,儘管看起來清晰很多,但意圖的表達仍然有些不明確
<!-- app.vue -->
<aside class="aside">
<!-- 顯示/隱藏側邊欄 -->
<img :class="['aside-toggle-show', {'aside-toggle-hide': isHide}]" />
<ul class="aside-menu">
<li class="aside-menu-item">首頁</li>
</ul>
</aside>
複製程式碼
/*css*/
.aside {}
.aside-toggle-show {}
.aside-toggle-hide {}
.aside-menu {}
.aside-menu-item {}
複製程式碼
/*scss或less*/
.aside {
&-toggle {
&-show {}
&-hide {}
}
&-menu {
&-item {}
}
}
複製程式碼
通過對比可以看到,BEM命名使得程式碼結構清晰多了,並且能把程式碼的意圖表達得很明確。
3. 正確地使用BEM
舉一個例子,你的手裡拿著一本書,但你不能說這本書是人的一部分。這就好比在程式碼中,有一個元素剛好某個塊中,但它本身並不屬於這個塊,按照BEM原則,此元素的命名不該包含進去:
<nav class="nav">
<ul class="nav__menu">
<li class="nav__menu__item">首頁</li>
</ul>
<!-- 顯示使用者名稱 -->
<span class="username">XXX 你好!</span>
</nav>
複製程式碼
後記
對於BEM命名規範本人還在實踐當中,也還存在一些疑問,例如在塊巢狀比較深時是否造成html程式碼冗長?待實踐一段時間有了新的想法再分享出來,大家有更好的命名方案歡迎在下方評論中分享。
感謝你的閱讀!