css BEM書寫規範

[規範]css BEM書寫規範

BEM是基於組件的web開發方法。其思想是將用戶界面分隔爲獨立的塊,從而使開發複雜的UI界面變得更簡單和快,且不須要粘貼複製即可複用現有代碼。 BEM由Block、Element、Modifier組成。 選擇器裏用如下鏈接符擴展他們的關係:css

  • `__:雙下劃線用來鏈接塊和塊的子元素
  • `- :僅做爲連字符使用,鏈接塊或元素或修飾符的多個單詞(也能夠直接寫成駝峯式)
  • --:雙中劃線用來鏈接塊或元素的狀態(也可以使用‘_’單下劃線表示,本文以'--'方式介紹)

示例: 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,html

基本概念

Block(塊)

代碼片斷可能被複用且這段代碼不依賴其餘組件便可用Block。塊能夠互相嵌套,能夠嵌套任意多層。git

特色:

  1. 塊的名稱用於描述它的目的。如 menu、button(而不是它的狀態,如:red、big)
  2. 塊不能影響所在環境。這意味着不能爲塊設置margin或position
  3. 只能使用class命名選擇器,而不能使用標籤或id選擇器
  4. 不依賴於頁面內其餘塊或元素

Element(元素)

Element是Block的一部分,沒有獨立存在的意義。任何一個Element語義上是和Block綁定的。github

特色:

  1. 與塊使用'__'鏈接。 如: block__item
  2. 用於描述它的目的。如:item、text
  3. 元素能夠彼此嵌套,能夠嵌套任意多層
  4. 元素老是屬於塊的一部分。因此相似於block__item1__item2的命名是不合法的

Modifier(修飾符)

定義Block或Element的外觀、狀態、或行爲的標記。web

特色:

  1. 與塊或元素鏈接符爲'--'
  2. Modifier描述的是它的外觀(如」什麼尺寸「或」什麼主題「等,如size_s或theme——islands),狀態(」它與其餘的哪裏不一樣「,如disabled,focused等)以及它的行爲(」它有怎麼樣的行爲「或」它是怎麼對用戶響應「,如directions_left-top)

Modifiers分類

Modifiers能夠當作是2種類型,key:true;key:value;即某個狀態,或某個狀態是什麼值。bash

Boolean:ide

  1. 只有當Modifiers的存在與否很重要時使用,這裏它的值默認是true。例如,disabled、active、clickable。
  2. 這種類型下樣式的結構是:
    • 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:佈局

  1. 當Modifiers的value才能描述完整一個狀態時,須要使用key-value.例如: 」一個以islands爲主題的菜單「,menu--theme--islands。
  2. 這種類型下樣式的結構是:
    • 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可以作到:ui

  1. 組合不一樣實體的行爲和樣式,而不須要複製代碼
  2. 基於現有的組件組合創造出新的組件 例如:
<!-- `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 {}
複製代碼

一些問題

  1. 最小化選擇器的嵌套(建議不超過2級)。嵌套的場景能夠出如今有modifier時,Block或Element須要修改樣式
  2. BEM自己是能夠寫成B__E__E的格式,但若是出現這種嵌套很深的狀況,說明組件化設計有問題,因此代碼開發中,要求不能寫這種格式代碼
  3. 不要使用id選擇器或tag選擇器
  4. 不要在Block中設置position、margin等位置佈局相關設置。把可能發生變化的css屬性放到Modifiers上
  5. 從使用角度,小圖標使用icon-作前綴,不需使用BEM
  6. 命名空間問題。目前咱們要求頁面以page-做爲Block,組件以組名名做爲Block。css-guidelines中提出相似BEM命名的方式,以一些前綴做爲標識。

注意: 一、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>
複製代碼

參考: en.bem.info

相關文章
相關標籤/搜索