【譯】BEM CSS命名規范一 Quick start

BEM 是對 CSS 命名的一種規范,推崇將 WEB 頁面模塊化,從而提高代碼的重用度,減少后期維護的成本。原文

快速開始

簡介

BEM(Block,Element,Modifier)是一個基于組件方式的 web 開發方法。
??他的基本思想是將用戶界面分為獨立的模塊。
??即使是一個復雜的 UI 界面,也會使得用戶界面開發簡單而迅速,,并且允許重用現有的代碼,而不是復制粘貼。

內容

  • 模塊
  • 元素
  • 我應該創建一個 Block 還是一個 Element
  • 修飾符
  • 混合模式
  • 文件系統

模塊

一個可重復使用的功能獨立的頁面組件。在 HTML 中,blocks 通過 class 屬性表示。
特征:

  • 模塊名稱描述了它的目的(“它是什么?” —— 菜單或者按鈕),而不是它的狀態(“它看起來是什么樣子?” —— 紅色或者大的)。

例如:

<!-- 正確的,這個 'error' 模塊是具有語義上的意義的 -->
<div class="error"></div>
<!-- 不正確的,它描述了模塊的外觀 -->
<div class="red-text"></div>
  • 模塊不應該影響它所在的環境,這意味著你不應該為模塊設置會影響到外部的形狀(影響大小的 padding 或邊框)和定位
  • 你也不應該在使用 BEM 的時候使用 CSS 標簽選擇器和 ID 選擇器

這些保證了模塊必要的獨立性,可以更好地重用模塊或者將他們從一個地方移動到另一個地方。

模塊使用指南

嵌套關系

  • 模塊與模塊之間可以彼此嵌套
  • 你可以有任意級別的嵌套層次

例子:

<!-- 'head' 模塊 -->
<header class="header">
    <!-- 嵌套 'logo' 模塊 -->
    <div class="logo"></div>

    <!-- 嵌套 'search-form' 模塊 -->
    <form class="search-form"></form>
</header>

元素

是一個模塊的組成部分,且不能脫離模塊單獨地被使用。

特征:

  • 元素名稱描述了它的目的(用處)(“這是什么?” —— item,text,等等。),而不是它的狀態(“什么類型的,或者它看起來是什么樣的?” —— 紅色,大的,等等。)
  • 完整的元素名的結構是 block-name__element-name。元素的名字與模塊的名字使用雙下劃線分隔(__)

例子:

<!-- 'search-form' 模塊 -->
<form class="search-form">
    <!-- 在 'search-form' 模塊內的 'input' 元素 -->
    <input class="search-form__input"/>
    <!-- 在 'search-form' 模塊內的 'button' 元素 -->
    <button class="search-form__button"></button>
</form>

元素使用指南

  • 嵌套關系
  • 組成部分
  • 可選性

嵌套關系

  • 元素之間可以彼此嵌套
  • 你可以擁有任意層次的嵌套級別
  • 一個元素總是一個模塊的一部分,而不是另一個元素的一部分,這意味著元素的名稱不能被定義為 block__elem1__elem2 這樣的層次結構。

例子:

<!--
     正確的。完整的元素名的結構符合如下模式:
     '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>

 <!--
     不正確的。完整的元素名的結構不符合如下模式:
     'block-name__element-name'
 -->
<form class="search-form">
    <div class="search-form__content">
        <!-- 推薦:'search-form__input' 或者 'search-form__content-input' -->
        <input class="search-form__content__input"/>
        <!-- 推薦:'search-form__button' 或者 'search-form__content-button' -->
        <button class="search-form__content__button"></button>
    </div>
</form>

如果在模塊名稱上定義了命名空間,也要保證元素名稱是依賴于模塊的(block_elem)。
??在 DOM 樹中,一個模塊可以有元素嵌套結構:
例子

<div class="block">
    <div class="block_elem1">
        <div class="block_elem2">
            <div class="block_elem3"></div>
        </div>
    </div>
</div>

然而,在 BEM 的方法論中,這樣的模塊結構通常表示為一個并列的元素列表:
例子

.block {}
.block_elem1 {}
.block_elem2 {}
.block_elem3 {}

這樣在代碼中,你可以在不改變每個單獨的元素的情況下改變一個模塊的 DOM 結構:
例子

<div class="block">
    <div class="block_elem1">
        <div class="block_elem1"></div>
    </div>
    <div class="block_elem3"></div>
</div>

模塊的結構改變了,但是元素的規則和他們的名字仍然保持不變。

組成部分

一個元素總是一個模塊的一部分,你不應該單獨使用它。
例子

<!-- 正確的。元素都位于 'search-form' 模塊內 -->
<!-- 'search-form' 模塊 -->
<form class="search-form">
    <!-- 在 'search-form' 模塊內的 'input' 元素 -->
    <input class="search-form__input" />
    <!-- 在 'search-form' 模塊內的 'button' 元素 -->
    <button class="search-form__button"></button>
</form>

<!-- 不正確的。元素位于 'search-form' 模塊的上下文之外 -->
<!-- 'search-form' 模塊 -->
<form class=""search-block>
</form>

<!-- 在 'search-form' 模塊內的 'input' 元素 -->
<input class="search-form__input"/>

<!-- 在 'search-form' 模塊內的 'button' 元素 -->
<button class="search-form__button"></button>

可選性

一個元素是一個可選的模塊組件。并不是所有的模塊都必須有元素。
例子:

<!-- 'search-form' 模塊 -->
<div class="search-form">
    <!-- 'input' 模塊 -->
    <input class="input"/>

    <!-- 'button' 模塊 -->
    <button class="button"></button>
</div>

我應該創建一個模塊還是一個元素?

  1. 如果這段代碼可能被重用,并且它不依賴于頁面上的其他組件,那你應該創建一個模塊。
  2. 如果這段代碼在沒有父實體(模塊)的情況下不能使用,那你應該創建一個元素。

為了簡化開發,元素應該被分割成一小部分-子元素。在 BEM 方法論中,你不能創建元素的元素,在這種情況下,你需要創建一個服務模塊,而不是創建一個元素。

修飾符

一種用于定義模塊和元素的外觀,狀態和行為的實體。
特征:

  • 修飾符的名稱描述了它的外觀(“多大?”或者“它的主題是什么?”等等—— size_s 或者 theme_islands),它的狀態(“它與其他有什么不同?” —— disabledfocused,等等)以及他的行為(“它的行為什么?”或者“它如何響應用戶?”——比如 directions_left-top)。
  • 修飾符的名字與模塊或者元素的名字使用單下劃線分隔(_)

修飾符的類型

Boolean

  • 當修飾符的存在或不存在是重要的,與它的值無關時使用這種類型的修飾符。比如:disabled。如果一個布爾類型的修飾符是可見的,它的值被假定為 true
  • 修飾符的全名的結構遵循如下模式:
    • block-name_modifier_name
    • block-name__element-name_modifier-name

例子

<!-- 'search-form' 模塊有一個 ‘focused’ 的布爾類型的修飾符 -->
<form class="search-form search-form_focused">
    <input class="search-form__input"/>

    <!-- 'button' 元素有一個 'disabled' 的布爾類型修飾符 -->
    <button class="search-form__button search-form__button_disabled">Search</button>
</form>

鍵-值

  • 當修飾符的值是重要的使用鍵值對類型。例如:“一個 islands 設計主題的按鈕”:menu_theme_islands
  • 這種類型的修飾符的全名的結構遵循如下模式:
    • block-name_modifier-name_modifier-value
    • block-name__element-name_modifier-name_modifier-value

例子

<!-- The `search-form` 模塊有值為 'islands' 的 `theme` 修飾 -->
<form class="search-form search-form_theme_islands">
    <input class="search-form__input">

    <!-- The `button` 元素有值為 'm' 的 `size` 修飾 -->
    <button class="search-form__button search-form__button_size_m">Search</button>
</form>

<!-- 你不能同時使用兩個具有不同值的的相同修飾符 -->
<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>

修飾符使用指南

一個修飾符不能被單獨使用。

從 BEM 的角度,一個修飾符不能脫離模塊或元素而被使用。一個修飾符應該改變實體的外觀,行為或者狀態,而不是替換它。
例子

<!-- 正確的。'search-form' 模塊有值為 'islands' 的 'theme' 修飾符 -->
<form class="search-form search-form_theme_islands">
    <input class="search-form__input">

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

<!-- 不正確的。'search-form' 丟失了 -->
<form class="search-form_theme_islands">
    <input class="search-form__input">

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

[為什么需要在元素或修飾符的名稱上添寫上模塊的名稱?](Why write the block name in the names of modifiers and elements?)

混合模式

一種在單一的 DOM 節點上使用不同 BEM 實體的技術。
混合模式允許你:

  • 結合多個實體的行為和樣式,而不是重復編寫代碼
  • 在現有代碼的基礎上創建具有新語義的 UI 組件

例子:

<!-- 'header' 模塊 -->
<div class="header">
    <!--
        將 'header' 模塊的 'search-form' 元素與 'search-form' 模塊混合在一起使用
    -->
    <div class="search-form header__search-form"></div>
</div>

在這個例子中,我們將 header 模塊的 search-form 元素與 search-form 模塊的行為和樣式結合在一起。這種方式允許我們在 header__search-form 元素上設置額外的形狀和定位,而 search-form 模塊仍然是通用的。因此,我們可以在任何環境中使用模塊,因為模塊沒有指定任何填充。這正是我們可以獨立調用模塊的原因。

文件系統

在 BEM 方法論中采用的組件概念同樣適用于項目的文件結構中。模塊、元素和修飾符的實現可以被分在獨立的文件中,這意味著,我們單獨地使用它們。
特征:

  • 一個單獨的模塊對應一個單獨地目錄
  • 模塊和其對應的目錄擁有相同的名字。比如, header 模塊放置在 header/ 目錄中,menu 模塊放置在 menu/ 目錄中。
  • 一個模塊的實現分為單獨的文件。比如, header.cssheader.js
  • 模塊目錄是其元素和修飾所在目錄的根目錄。
  • 元素目錄的名稱以雙下劃線(__)開始。比如,header/__logo/ 和 menu/__item
  • 修飾目錄的名稱以單下劃線(_)開始。比如,header_fixedmenu/_theme_islands/
  • 元素和修飾的實現分為不同的文件。比如,header__input.jsheader_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

這樣的文件結構可以很好地支持我們重用代碼。

在生產環境中,這些分支的文件結構將會被組合成共享的文件。

遵循這樣的文件結構并不是必須的。你可以使用任何可替代的項目結構,根據 BEM 原則來組織你的文件結構,比如:

自己英文水平有限,如果文中有錯誤,或者歧異,或者不恰當的地方,希望大家提出來,非常愿意接受大家的批評與建議。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容