[規范]css BEM書寫規范
BEM是基于組件的web開發方法。其思想是將用戶界面分隔為獨立的塊,從而使開發復雜的UI界面變得更簡單和快,且不需要粘貼復制便可復用現有代碼。 BEM由Block、Element、Modifier組成。 選擇器里用以下連接符擴展他們的關系:
- `__:雙下劃線用來連接塊和塊的子元素
- `- :僅作為連字符使用,連接塊或元素或修飾符的多個單詞(也可以直接寫成駝峰式)
- --:雙中劃線用來連接塊或元素的狀態(也可使用‘_’單下劃線表示,本文以'--'方式介紹)
示例: block-name_modifier-name block-name__element-name--modifier-name block-name_modifier-name--modifier-value block-name__element-name--modifier-name--modifier-value 代碼里能出現的樣式組合只能是B B__E B--M B__E--M B__E--M--M,
基本概念
Block(塊)
代碼片段可能被復用且這段代碼不依賴其他組件即可用Block。塊可以互相嵌套,可以嵌套任意多層。
特點:
- 塊的名稱用于描述它的目的。如 menu、button(而不是它的狀態,如:red、big)
- 塊不能影響所在環境。這意味著不能為塊設置margin或position
- 只能使用class命名選擇器,而不能使用標簽或id選擇器
- 不依賴于頁面內其他塊或元素
Element(元素)
Element是Block的一部分,沒有獨立存在的意義。任何一個Element語義上是和Block綁定的。
特點:
- 與塊使用'__'連接。 如: block__item
- 用于描述它的目的。如:item、text
- 元素可以彼此嵌套,可以嵌套任意多層
- 元素總是屬于塊的一部分。所以類似于block__item1__item2的命名是不合法的
Modifier(修飾符)
定義Block或Element的外觀、狀態、或行為的標記。
特點:
- 與塊或元素連接符為'--'
- Modifier描述的是它的外觀(如”什么尺寸“或”什么主題“等,如size_s或theme——islands),狀態(”它與其他的哪里不同“,如disabled,focused等)以及它的行為(”它有怎么樣的行為“或”它是怎么對用戶響應“,如directions_left-top)
Modifiers分類
Modifiers可以看成是2種類型,key:true;key:value;即某個狀態,或某個狀態是什么值。
Boolean:
- 只有當Modifiers的存在與否很重要時使用,這里它的值默認是true。例如,disabled、active、clickable。
- 這種類型下樣式的結構是:
- block-name--modifier-name
- block-name__element-name--modifier-name
例如:
<form class="search-form search-form--focused">
<input class="search-form__input">
<!-- The `button` element has the `disabled` Boolean modifier -->
<button class="search-form__button search-formbutton__button--disabled">Search</button>
</form>
復制代碼
key-value:
- 當Modifiers的value才能描述完整一個狀態時,需要使用key-value.例如: ”一個以islands為主題的菜單“,menu--theme--islands。
- 這種類型下樣式的結構是:
- block-name_modifier-name--modifier-value
- block-name__element-name--modifier-name--modifier-value 例如:
<!-- 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">Search</button>
</form>
</form>
復制代碼
Mix
一種在一個DOM節點上使用不同BEM的方法。 Mixes能夠做到:
- 組合不同實體的行為和樣式,而不需要復制代碼
- 基于現有的組件組合創造出新的組件 例如:
<!-- `header` block -->
<div class="header">
<!--
The `search-form` block is mixed with the `search-form` element
from the `header` block
-->
<div class="search-form header__search-form"></div>
</div>
復制代碼
通過在search-form Block本身是不能設置position或margin,放在header里后,可以作為header的元素,我們在header__search-form上可以設置它的位置信息。所以寫組件的時候,可以為組件預留一個className props。
應用
相對另外的Blocks定位Block
最好的方式是混合使用block和element。解決block上不能設置margin、position。 例:
<body class="page">
<!-- header and navigation-->
<header class="header page__header">...</header>
<!-- footer -->
<footer class="footer page__footer">...</footer>
</body>
復制代碼
.page__header {
padding: 20px;
}
.page__footer {
padding: 50px;
}
復制代碼
Block內定位Elements
通過額外創建Block的子Element來定位嵌套。 例:
<body class="page">
<div class="page__inner">
<!-- header and navigation-->
<header class="header">...</header>
<!-- footer -->
<footer class="footer">...</footer>
</div>
</body>
復制代碼
.page__inner {
margin-right: auto;
margin-left: auto;
width: 960px;
}
復制代碼
關于命名
選擇器的命名必須完整且精確地描述它代表的BEM實體。 例:
.button {}
.button__icon {}
.button__text {}
.button--theme--islands {}
復制代碼
我們可直接指導我們在處理一個塊元素。在html使用如:
<button class="button button_theme_islands">
<span class="button__icon"></span>
<span class="button__text">...</span>
</button>
復制代碼
而下面的css就很難讓我們做出相同的判斷:
.button {}
.icon {}
.text {}
.theme--islands {}
復制代碼
一些問題
- 最小化選擇器的嵌套(建議不超過2級)。嵌套的場景可以出現在有modifier時,Block或Element需要修改樣式
- BEM本身是可以寫成B__E__E的格式,但如果出現這種嵌套很深的情況,說明組件化設計有問題,所以代碼開發中,要求不能寫這種格式代碼
- 不要使用id選擇器或tag選擇器
- 不要在Block中設置position、margin等位置布局相關設置。把可能發生變化的css屬性放到Modifiers上
- 從使用角度,小圖標使用
icon-
做前綴,不需使用BEM - 命名空間問題。目前我們要求頁面以
page-
作為Block,組件以組名名作為Block。css-guidelines中提出類似BEM命名的方式,以一些前綴作為標識。
注意: 1、BEM中的命名嵌套和DOM不是嚴格綁定的,命名上不要使用B__E__E,但是寫DOM時和樣式沒有關系。B__E下的DOM里仍然可以有B__E樣式的DOM.命名規范是用于識別頂層塊組件之間的關系。 例如:
<div class="menu">
<div class="menu__header">
<h2 class="menu__title">Title text here</h2>
</div>
<div class="menu__body">
<img class="menu__img" src="img.png" alt="description" />
<p class="menu__text">text</p>
<p class="menu__text">
<a href="test.html" class="menu__link">link</a>
</p>
</div>
</div>
作者:midsummer12361
鏈接:https://juejin.cn/post/6844903740978249735
來源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。