重要概念
- Block(塊,并不是平常說的塊級元素中的塊,而是指模塊、組件)
- Element(元素 )
- Modifier(修飾符 )
- BEM entity(BEM 實體)
- Mix(混合體)
- BEM tree(BEM 樹 )
- Block implementation(塊實現(xiàn) )
- Block implementation technology (塊實現(xiàn)技術(shù) )
- Block redefinition (塊重定義 )
- Redifinition level(重定義等級 )
1. Block(塊)
Block 是一個邏輯上和功能上獨立的頁面組件,等同于網(wǎng)頁組件中的部件(等同于網(wǎng)頁中的組件)。Block 封裝了行為(Javascript)、模板、樣式(CSS)和其他實現(xiàn)技術(shù)。獨立狀態(tài)的 Block 可供復(fù)用,并且促進項目開發(fā)和維護。
Block 的特點
嵌套式的構(gòu)造
Block 可以被嵌套到任何其他 block 里面去。例如,一個頭部 block 可以包含一個 logo、一個搜索表單和一個登錄 block。

隨意放置
Block 可以在一個頁面內(nèi)任意移動,也可以在頁面之間或項目之間移動。Block 作為獨立的實體來實現(xiàn),這使得在頁面上改變 block 的位置 并確保其功能和外觀一切正常 成為可能。
因此,即使不修改 block 的 CSS 和 Javascript 代碼,logo 和 登錄表單 也可以到處切換(譯者注:即 logo 和 登錄表單 可以用在各個頁面各個項目中)。


可復(fù)用
一個界面可以包含同一個 block 的幾個實例。

2. Element(元素)
Element 是一個 block 的組成部分,它不能被拿到 block 的外面使用。例如,一個菜單項(a menu item )不會在一個菜單塊(a menu block )范圍之外使用,因此它是一個元素(element)。

什么時候應(yīng)該用 block?什么時候應(yīng)該用 element?(A block or an element: when should I use which? )
BEM 方法論不推薦大家在element 內(nèi)使用 element(Using elements within elements is not recommended by the BEM methodology )
3. Modifier(修飾符)
Modifier 是一個 BEM 實體,它定義了一個 block 或 element 的外觀和行為。
Modifier 可用也可不用(即不一定要用到 modifier)。
Modifier 本質(zhì)上與 HTML 的屬性很相似。同一個 block 會因為 modifier 的使用而 看起來與之前有所不同。
例如,菜單塊(the menu block )的外觀可能會因為在它身上用了一個 modifier 而改變。

4. BEM entity(BEM 實體)
Block,element 和 modifier 合起來就被成為 BEM entity。它是一個 既可以用來指代單獨的 BEM 實體又可以作為 block、element 和 modifier 的總稱的 概念。
5. Mix(混合體)
Mix 是被托管在(being hosted on)一個單獨的 DOM 節(jié)點上的 不同 BEM 實體(混合而成)的一個實例。
Mix 允許我們:
- 把幾個 BEM 實體的功能(behavior)和樣式 組合在一起,同時避免重復(fù)代碼
- 在現(xiàn)有的 BEM 實體的基礎(chǔ)上 創(chuàng)建語義上的新界面組件。讓我們想一下這種 mix 情形:把一個 block 與 另一個 block 的一個 element 組合在一起。
我們假設(shè),項目里的鏈接(links)通過一個鏈接塊(a link block)來實現(xiàn)。我們需要把菜單項(menu items )格式化成鏈接(links)。這里有幾種實現(xiàn)方法:
- 創(chuàng)建一個 可以把菜單項(item)轉(zhuǎn)變成鏈接(link)的 modifier。實現(xiàn)這樣一個 modifier 即必然牽涉到 復(fù)制鏈接塊的功能和樣式。這樣一來就會導(dǎo)致代碼重復(fù)。
- 取一個 把一個通用的鏈接塊(link block )與一個菜單塊的一個鏈接元素(a link element ) 組合在一起的 mix。兩個 BEM 實體的混合體(mix)可以讓我們不用復(fù)制代碼,就可以使用鏈接塊的基本鏈接功能 和 菜單塊的 CSS 規(guī)則。
6. BEM tree(BEM 樹)
BEM tree 是網(wǎng)頁結(jié)構(gòu)在 block、element 和 modifier 方面的表示(representation)。這是一個在 DOM 樹之上的抽象概念,它描述了 BEM 實體的名稱、它們的狀態(tài)、順序、嵌套和輔助數(shù)據(jù)。在現(xiàn)實生活中的項目,BEM tree
可以呈現(xiàn)在任何支持樹結(jié)構(gòu)的形式(format)中。
讓我們看一下 DOM 樹的一個例子:
<header class="header">
<img class="logo">
<form class="search-form">
<input type="input">
<button type="button"></button>
</form>
<div class="lang-switcher"></div>
</header>
對應(yīng)的 BEM tree 看起來是這樣子的:
header
├──logo
└──search-form
├──input
└──button
└──lang-switcher
在 XML 和 BEMJSON 格式中,該 BEM tree 則是這樣的:
XML
<block:header>
<block:logo/>
<block:search-form>
<block:input/>
<block:button/>
</block:search-form>
<block:lang-switcher/>
</block:header>
BEMJSON
{
block: 'header',
content : [
{ block : 'logo' },
{
block : 'search-form',
content : [
{ block : 'input' },
{ block : 'button' }
]
},
{ block : 'lang-switcher' }
]
}
7. Block implementation(BEM 實現(xiàn))
Block implementation 是指一組各不相同的 技術(shù),這些技術(shù)決定著 BEM 實體以下幾方面:
- 行為/功能(behavior)
- 外觀
- 測試
- 模板
- 文檔(documentation)
- 依賴描述
- 附加數(shù)據(jù)(例如:圖片)
8. Implementation technology(實現(xiàn)技術(shù))
Implementation technology 是一種用于實現(xiàn) 一個 block 的技術(shù)。Block 可以用一種或多種技術(shù)來實現(xiàn),例如:
- 行為/功能(behavior)-- JavaScript, CoffeeScript
- 外觀-- CSS, Stylus, Sass
- 模板-- BEMHTML, BH, Jade, Handlebars, XSL
- 文檔(documentation)-- Markdown, Wiki, XML
例如,如果一個 block 的外觀是用 CSS 來定義的,這意味著 block 是用 CSS 技術(shù)實現(xiàn)的。同樣地,如果一個 block 的文檔是用 Markdown 格式寫的,block 就是用 Markdown 技術(shù)來實現(xiàn)的。
9. Block redefinition(block 重定義)
Block implementation 是指通過在不同的層級上增加新的功能到 block 來修改 block。
10. Redefinition level(重定義級別)
Redefinition level 是指一組 BEM 實體和它們的部分實現(xiàn)。
一個 block 的最終實現(xiàn) 可以被分成 不同的重定義層級。每一個新的層級都會擴展或覆蓋原始的 block implementation。最終的結(jié)果由 來自所有按照預(yù)設(shè)的連續(xù)的順序排列的重定義層級的獨立的 block implementation technologies 組合而成。
任何 BEM 的實現(xiàn)技術(shù)都可以被重新定義。
例如,有一個連接到項目的第三方庫。這個庫包含現(xiàn)成的 block implementation。該項目指定的 block 保存在一個另一個重定義層級。比方說(Let's say ),我們需要修改這個庫里的某一個 block 的外觀。這并不需要在庫的源代碼里修改 block 的 CSS 規(guī)則 或者 在項目里復(fù)制代碼。我們只需在項目里為 那一個 block 創(chuàng)建額外的 CSS 規(guī)則。在生成過程中,所產(chǎn)生的實現(xiàn) 將會結(jié)合 來自庫的原始規(guī)則 與 來自項目的新樣式。(原文喜歡用 library level 和 project level,但翻譯的時候,直接理解為 library 和 project 就好)