BEM——前端命名規範介紹

anetin發表於2018-01-04

什麼是BEM?

BEM(Block, Element, Modifier)是由Yandex團隊提出的一種前端命名規範。其核心思想是將頁面拆分成一個個獨立的富有語義的塊(blocks),從而使得團隊在開發複雜的專案變得高效,並且十分有利於程式碼複用,即便團隊引入新成員,也容易維護。在某種程度上,BEM和OOP是相似的。

Block

Block是邏輯和功能獨立的單元,類似於元件。每個block包含自身的行為(js)、結構(HTML模板)、表現(css)。block的獨立性有利於程式碼的複用,有利於專案管理。

Block特點

1.block名描述block功能 (“What is it?” — menu or button), 不包含其狀態 (“What does it look like?” — red or big)。block可以巢狀、複用。

<!-- Correct. The `error` block is semantically meaningful -->
<div class="error"></div>

<!-- Incorrect. It describes the appearance -->
<div class="red-text"></div>

block可以巢狀,並且可以巢狀任意多個block

<!-- `header` block -->
<header class="header">
    <!-- Nested `logo` block -->
    <div class="logo"></div>

    <!-- Nested `search-form` block -->
    <form class="search-form"></form>
</header>

2.block不影響自身佈局,也就是說不能設定margin和position屬性。

3.不能在BEM中使用元素選擇器和ID選擇器。

Element

Element 是block的組成部分,並且不能脫離block使用。

Element特點

1.element表示其目的( item, text, etc.), 而不是其狀態( red, big, etc.).

2.Element的命名方式:block-name__element-name. element名字和block名字以雙下劃線分開。

<!-- `search-form` block -->
<form class="search-form">
    <!-- `input` element in the `search-form` block -->
    <input class="search-form__input">

    <!-- `button` element in the `search-form` block -->
    <button class="search-form__button">Search</button>
</form>

Element用法——巢狀

Elements 可以相互巢狀,並且巢狀數量任意。element只能是block的一部分,也就是說element的命名層級不能是block__elem1__elem2。

<!--
    Correct. The structure of the full element name follows the pattern:
    `block-name__element-name`
-->
<form class="search-form">
    <div class="search-form__content">
        <input class="search-form__input">

        <button class="search-form__button">Search</button>
    </div>
</form>

<!--
    Incorrect. The structure of the full element name doesn`t follow the pattern:
    `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一起使用,而是獨立定義規則。這樣,當修改bolck的結構時不需要修改css。

<div class="block">
    <div class="block__elem1">
        <div class="block__elem2">
            <div class="block__elem3"></div>
        </div>
    </div>
</div>
.block {}
.block__elem1 {}
.block__elem2 {}
.block__elem3 {}

The block`s structure changes, but the rules for the elements and their names remain the same.

<div class="block">
    <div class="block__elem1">
        <div class="block__elem2"></div>
    </div>

    <div class="block__elem3"></div>
</div>

Element與block的關係

elementy只能作為block的一部分使用,不能獨立使用。

<!-- Correct. Elements are located inside the `search-form` block -->
<!-- `search-form` block -->
<form class="search-form">
    <!-- `input` element in the `search-form` block -->
    <input class="search-form__input">

    <!-- `button` element in the `search-form` block -->
    <button class="search-form__button">Search</button>
</form>

<!--
    Incorrect. Elements are located outside of the context of
    the `search-form` block
-->
<!-- `search-form` block -->
<form class="search-form">
</form>

<!-- `input` element in the `search-form` block -->
<input class="search-form__input">

<!-- `button` element in the `search-form` block-->
<button class="search-form__button">Search</button>

block不一定含有element。

<!-- `search-form` block -->
<div class="search-form">
    <!-- `input` block -->
    <input class="input">

    <!-- `button` block -->
    <button class="button">Search</button>
</div>

何時用Element何時用block

使用block: If a section of code might be reused and it doesn`t depend on other page components being implemented.
建立element:If a section of code can`t be used separately without the parent entity (the block).

Modifier

Modifier定義block和element的外觀,狀態,或者行為。

Modifier 特徵

Modifier表示其表現(“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命名方法:以單下劃線與block 或者 element 隔開。

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">Search</button>
</form>

modifier型別:Key-value

<!-- You can`t use two identical modifiers with different values simultaneously -->
<form class="search-form
             search-form_theme_islands
             search-form_theme_lite">

    <input class="search-form__input">

    <button class="search-form__button
                   search-form__button_size_s
                   search-form__button_size_m">
        Search
    </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>

檔案組織結構

BEM理論也可以應用到工程目錄的組織架構中。blocks, elements, 和 modifiers將分開為獨立的檔案。

Features:

1.A single block corresponds to a single directory.

2.The block and the directory have the same name. For example, the header block is in the header/ directory, and the menu block is in the menu/ directory.

3.A block`s implementation is divided into separate technology files. For example, header.css and header.js.

4.The block directory is the root directory for the subdirectories of its elements and modifiers.

5.Names of element directories begin with a double underscore (__). For example, header/__logo/ and menu/__item/.

6.Names of modifier directories begin with a single underscore (_). For example, header/_fixed/ and menu/_theme_islands/.

7.Implementations of elements and modifiers are divided into separate technology files. For example, header__input.js and header_theme_islands.css.

search-form/                           # Directory of the search-form

    __input/                           # Subdirectory of the search-form__input
        search-form__input.css         # CSS implementation of the
                                       # search-form__input element
        search-form__input.js          # JavaScript implementation of the
                                       # search-form__input element

    __button/                          # Subdirectory of the search-form__button
                                       # element
        search-form__button.css
        search-form__button.js

    _theme/                            # Subdirectory of the search-form_theme
                                       # modifier
        search-form_theme_islands.css  # CSS implementation of the search-form block
                                       # that has the theme modifier with the value
                                       # islands
        search-form_theme_lite.css     # CSS implementation of the search-form block
                                       # that has the theme modifier with the value
                                       # lite

    search-form.css                    # CSS implementation of the search-form block
    search-form.js                     # JavaScript implementation of the
                                       # search-form block

參考更多

相關文章