CSS命名規範之BEM
What is BEM?
BEM:Block(塊) Element(元素) Modfier(修飾符),是由Yandex團隊提出的一種前端命名方法論。根據這個規範,能夠創建出可以複用的前端元件和前端程式碼。(BEM是一個高可用、強大的、簡單易用的命名規範)
程式設計方法論中常見的一個就是面向物件程式設計(OOP),這種方法用在了許多的語言中。BEM和OOP類似的,是用程式碼和一系列模式來描述實際情況的方法,只考慮程式實體而無所謂使用什麼程式語言。(摘自https://www.w3cplus.com/css/bem-definitions.html)
Why Choose BEM?
除了BEM規範以外還有其它的規範例如:
- OOCSS:用CSS“物件”分隔容器和內容
- SMACSS:風格指南為您的CSS編寫CSS規則的五個類別
- SUITCSS:結構化類名和有意義的連字元
- 原子:將樣式分解為原子或不可分割的部分
上面的方法都可以應用在專案中,無論使用哪一種方法,都將受益於更多結構化CSS和UI的優勢。一些風格不那麼嚴格和更靈活,而另一些則更容易理解和適應團隊。
使用的原因:它比其他方法(即SMACSS)更容易混淆,但仍為我們提供了我們想要的良好體系結構(即OOCSS)以及可識別的術語。 (摘自https://www.jianshu.com/p/339fdb93e155)
Features
- 簡單易用:只需要採用BEM命名規範就可以
- 單元性:獨立的塊和CSS選擇器,可以使得你的程式碼可以重用和單元化
- 靈活性:使用BEM之後,方法和工具可以按照自己喜歡的方式進行配置(XML 、JSON)
按元件劃分類名,減少層次關係,實現扁平化、語義化,通過唯一的類名來避免不必要的樣式繼承,提高渲染效率。
How To Use?
Block
命名規範:block-name
示例:
.block{}
.container{}
.blog-header{}
/*上面都是block的命名方式,其中第三個是block名字有多個單片語成使用-隔開*/
Block是邏輯和功能相對獨立的單元,類似於元件。每個block包含自己的行為(js)、結構(html模板)、表現(css)。block的獨立性有利於程式碼的複用,有利於專案的管理。
(1)block名描述block功能,不能包含其狀態,block可以巢狀、複用
- 描述功能就是描述這個block是幹什麼的?例如menu、carboard等等
- 不能包含其狀態就是不能描述它的表現,例如一個button,那麼不能描述它是什麼樣子red,blue
<!--正確的寫法-->
<div class="error"></div>
<!--錯誤的寫法,block包含了狀態-->
<div class="red-text"></div>
巢狀的block
<div class="header">
<div class="logo"></div>
<div class="search-form"></div>
</div>
- block不能夠影響自身的佈局,就是不能為block設定margin和position屬性
- 不能在BEM中使用元素選擇器和ID選擇器
Element(element只能作為block的一部分使用,不能獨立使用)
命名規範:block-name__element-name
(中間的-是名字如多個單詞,使用的-連線)
示例:
.block__mod{}
.block-body__mod{}
一個元素是塊的一部分,具有某種功能。元素是依賴上下文的:它們只有處於他們應該屬於的塊的上下文中時才是有意義的。
- element表示其目的(item,text…..),不是描述他的狀態
- 命名格式為:block-name__element-name,其中的element名字和block名字以雙下劃線分開
<form class="search-form">
<!--下面的`input`element在`search-form`block之中-->
<input class="search-form__input"/>
<button class="search-form__button">搜尋</button>
</form>
- elements同樣可以相互巢狀,數量不限
<!-- 正確. 下面整個element命名符合規範:`block-name__element-name`-->
<form class="search-form">
<div class="search-form__content">
<input class="search-form__input"/>
<button class="search-form__button"></button>
</div>
</form>
<!--不正確的示例,下面的element命名不符合規範:`block-name__element-name`-->
<form class="search-form">
<div class="search-form__content">
<!-- Recommended: `search-form__input` or `search-form__content-input` -->
<input class="search-form__content__input">
<!-- Recommended: `search-form__button` or `search-form__content-button` -->
<button class="search-form__content__button">Search</button>
</div>
</form>
block決定了名稱空間,確保elements不被其他block影響。block中的element在css中不需要跟block一起使用,而是獨立的定義規則,這樣當修改block結構的時候不需要修改css。示例如下:
<style>
.block{}
.block__elem1{}
.block__elem2{}
.block__elem3{}
</style>
<!--未修改之前-->
<div class="block">
<div class="block__elem1">
<div class="block__elem2">
<div class="block__elem3"></div>
</div>
</div>
</div>
<!--修改結構,element的規則和他們的命名依然保持不變-->
<div class="block">
<div class="block__elem1">
<div class="block__elem2"></div>
</div>
<div class="block_elem3"></div>
</div>
When to use element?When to use block?
block:如果一段程式碼可以重用,而不依賴於正在執行的其他頁面元件。這個時候使用block
element:如果一段程式碼不能脫離父模組獨立存在,那麼使用element
Modifier
命名規範:
- 有值
block-name__element-name--modifier-value
,block-name--modifier-value
- 無值
block-name__element-name--modifier
,block-name--modifier
示例:
.block__elem--mod{}/*這個是沒有值的修飾符*/
.block__elem--mod-value{}/*這是修飾符帶有值,帶有值的修飾符通過-將修飾符和值隔開key-value形式*/
.block--mod{}/*這個是對塊的描述,不帶值*/
.block--mod-value{}/*這個是對塊的描述,帶有值*/
Modifier定義block和element的外觀,狀態或者行為。
- 表示表現(“What size? ” or “Which theme?” and so on — size_s or theme_islands),
- 表示狀態(“How is it different from the others?” — disabled, focused, etc. )
- 表示行為(“How does it behave?” or “How does it respond to the user?” — such as directions_left-top )
modifier的型別為Boolean例子(帶有值):
<!-- The `search-form` block has the `theme` modifier with the value `islands` -->
<form class="search-form search-form--theme-islands">
<input class="search-form__input"/>
<!-- The `button` element has the `size` modifier with the value `m` -->
<button class="search-form__button search-form__button--size-m"></button>
</form>
modifier的型別為key-value的例子:
<form class="search-form search-form_theme_islands search-form_theme_lite">
<!-- The `input` elemen -->
<input class="search-form__input"/>
<button class="search-form__button search-form__button--size-s search-form__button--size-m">
</button>
</form>
modifier不能夠單獨使用
<!--
Correct. The `search-form` block has the `theme` modifier with
the value `islands`
-->
<form class="search-form search-form--theme-islands">
<input class="search-form__input">
<button class="search-form__button">Search</button>
</form>
<!-- Incorrect. The modified class `search-form` is missing -->
<form class="search-form--theme-islands">
<input class="search-form__input">
<button class="search-form__button">Search</button>
</form>