前端領域的BEM究竟是什麼

在這篇【譯】什麼是CSS Modules ?咱們爲何須要他們?的結尾處,明確指出CSS Modules不須要BEM,那麼BEM究竟是什麼呢?前端

下面我將把BEM官網的教程翻譯出來,帶領你們搞清楚前端領域的BEM究竟是什麼。git

BEM - Block Element Modfier(塊元素編輯器)是一個頗有用的方法,它能夠幫助你建立出能夠複用的前端組件和前端代碼程序員

它有以下3個特性:github

  • 易用性 若是想使用BEM,你只須要採用BEM命名規範便可
  • 單元性 獨立的塊和CSS選擇器,可使得你的代碼可重用和單元化
  • 靈活性 使用BEM以後,方法和工具能夠按照你喜歡的方式去組織和配置

下面將從3個方面來分析BEM究竟是什麼?shell

  • 介紹

BEM是一個高可用的,強大的,並且簡單的命名規範,它可使得你的前端代碼更加易讀和理解,容易與他人協做,容易擴展,更增強壯和明確,關鍵是更加嚴謹。瀏覽器

  • 命名

BEM的方法,能夠確保參與網站開發的每個人,都可以使用一個代碼庫而且使用同一種語言。使用BEM格式的命名規範,能夠從容應對需求變動。緩存

  • FAQ編輯器

    • 爲何不適用語義化的標籤而是直接去使用爲塊元素添加CSS class呢?
    • 我能夠像button.button的方式去組合標籤和class到同一個選擇器中嗎?

還要更多的疑惑,能夠查看FAQ列表!ide

介紹

在小型手冊網站上,如何組織你的風格一般不是一個大問題。你進入那裏,寫一些CSS,或者甚至是一些SASS。用SASS的生產設置將它編譯成一個樣式表,而後將它聚合到一塊兒,將模塊中的全部樣式表都變成一個很好的整潔包。工具

可是,當涉及到更大,更復雜的項目時,組織代碼的方式至少有如下三種方式是提升效率的關鍵:它影響編寫代碼須要多長時間,須要多少代碼寫和你的瀏覽器將不得不作多少加載。當你與團隊合做而且高性能是必不可少的時候,這變得尤其重要。

這對於使用遺留代碼的長期項目也是如此(請參閱「如何使用Sass和SMACSS來擴展和維護傳統CSS」 - 一些不錯的SMACSS和BEM混合)。

方法
目前有不少方法能夠減小CSS佔用空間,組織程序員之間的合做以及維護大型CSS代碼庫。這在Twitter,Facebook和Github等大型項目中很明顯,但其餘項目一般會很快成長爲「巨大的CSS文件」狀態。

  • OOCSS 用CSS「對象」分隔容器和內容
  • SMACSS 風格指南爲您的CSS編寫CSS規則的五個類別
  • SUITCSS 結構化類名和有意義的連字符
  • 原子 將樣式分解爲原子或不可分割的部分

爲何BEM比其餘人更好?
不管您選擇在項目中使用哪一種方法,您都將受益於更多結構化CSS和UI的優點。一些風格不那麼嚴格和更靈活,而另外一些則更容易理解和適應團隊。

我選擇BEM而不採用其餘方法的緣由歸結爲:它比其餘方法(即SMACSS)更容易混淆,但仍爲咱們提供了咱們想要的良好體系結構(即OOCSS)以及可識別的術語。
Mark McDonnell,BEM可維護的CSS

Blocks,Element和Modifier
聽到BEM是方法論的關鍵元素 - Block,Element和Modifier的縮寫,您必定不會感到驚訝。BEM嚴格的命名規則能夠在這裏找到。

    • 獨立的實體,它自己是有意義的。
    • 例子 header,container,menu,checkbox,input
  • 元件

    • 塊的一部分,沒有獨立的含義,而且在語義上與其塊相關聯。
    • 例子 menu item,list item,checkbox caption,header title
  • 修改

    • 塊或元素上的標誌。用它們來改變外觀或行爲。
    • 例子 disabled,highlighted,checked,fixed,size big,color yellow

image

深刻理解
咱們如今來看一個使用BEM的元素,是Github的button:
image

咱們可使用一個普通按鈕應對普通狀況 ,再使用兩種不一樣的應對不一樣狀況。由於咱們使用BEM的方式爲Block 綁定了class,咱們能夠用任何想使用的標籤去實現。(button,a 甚至是div)。可是命名規則告訴咱們須要使用block-modifier-value的語法。
HTML:

<button class="button">
    Normal button
</button>
<button class="button button--state-success">
    Success button
</button>
<button class="button button--state-danger">
    Danger button
</button>

CSS:

.button {
    display: inline-block;
    border-radius: 3px;
    padding: 7px 12px;
    border: 1px solid #D5D5D5;
    background-image: linear-gradient(#EEE, #DDD);
    font: 700 13px/18px Helvetica, arial;
}
.button--state-success {
    color: #FFF;
    background: #569E3D linear-gradient(#79D858, #569E3D) repeat-x;
    border-color: #4A993E;
}
.button--state-danger {
    color: #900;
}

優勢:

  • 單元性

塊的樣式歷來不依賴同頁面其它的元素,因此你永遠不會遇到級聯問題。您還能夠將完成的項目中的塊轉移到新項目中。

  • 重用性

不一樣方式組織獨立的塊,並智能地重用它們,能夠減小必須維護的CSS代碼量。經過一系列風格指南,您能夠構建一個塊庫,使您的CSS超級有效。

  • 結構化

BEM方法可使得你的CSS代碼結構性很好,從而更加容易理解。

拓展閱讀
‘Why BEM?’ in a nutshell
MindBEMding — getting your head ’round BEM syntax
CSS guidelines
BEM methodology for small projects
BEM It! for Brandwatch
Used and Abused — CSS Inheritance and Our Misuse of the Cascade.
Objects in Space — A style-guide for modular SASS development using SMACSS and BEM
How to Scale and Maintain Legacy CSS with Sass and SMACSS
Building a modular My Health Skills with BEM and Sass
Building My Health Skills — Part 3

案例分析:
咱們但願儘快撰寫「如何將現有項目遷移到BEM」。與此同時,您能夠觀看Nicole Sullivan的精彩演講 - 「CSS預處理器性能」。她很好地概述了她在大多數網站遇到的問題,並提供了跟蹤和處理這些問題的方法。

命名

在計算機科學領域,只有2個很是難解決的問題:一個是緩存失效,而另外一個則是命名。-Phil Karlton

有一個好的樣式指導手冊將會顯著提升開發的速度,debug的速度,以及在原有代碼上完成新功能的效率。然而不幸的是,大多數的CSS 代碼在開發過程當中毫無任何結構和命名的規範。從長遠角度來看,這會致使最後產生的CSS代碼庫很難維護。

BEM方法確保每個參加了同一網站開發項目的人,基於一套代碼規範去開發,這樣很是有利於團隊成員理解彼此的代碼,並且對於後續接手項目的同窗來講,也是一件好事。

Block

  • 封裝一個只對本身有意義的實體。當blocks可以被嵌套並且彼此之間能夠交互的時候,語義上他們是等價的;沒有層級關係。沒有DOM表示的總體實體。(例如控制器和模型也能夠是塊)
  • Naming Block的名字包含拉丁字母,數字和句號。當組合一個完整CSS class的時候,能夠增長一個短的前綴:.block
  • HTML 任何DOM節點能夠做爲一個Block,只要它接受一個class名。<div class="block">...</div>
  • CSS

    • 只使用class名選擇器
    • 沒有標籤名和或者id
    • 同一頁面裏,不依賴其它的block或者element
    • 例如.block {color:#042;}

Element

  • Block的一部分,當把它獨立取出來時,沒有任何實際意義。任何元素在語義上都是它本身的block緊密相連的。
  • Naming Element的名字可能包含拉丁字母,數字,句號以及下劃線。CSS class名由block名成加兩個下劃線再加element的名字,最後組織成一個塊名。
  • HTML 任何的在Block中的DOM節點,都是一個element。在一個已知的block中,全部的element在語義上都是相等的。
<div class="block">
    <span class="block__name"></span>
</div>
  • CSS

    • 只選擇class名字做爲選擇器
    • 沒有標籤名或者id
    • 不依賴當前頁面的其它block或者element

Good

.block__elem{color:#042};

Bad

.block .block__elem {color:#042;}
div.block__elem {color:#042;}

Modifier

  • block或者element的flag。使用他們能夠改變樣式,行爲或者是狀態。
  • Naming Modifier的名字能夠包含拉丁字母,數字,句號以及下劃線。CSS的class能夠由block或者element名稱後面加--組成,例如.block--mod或者.block__elem--mod,以及.block--color-black .block--color-red。複雜的modifier裏由短線替代空格。

-HTML Modifier是一個額外的加在block或者element class名以後一個class 名。只爲他們負責修改的blocks或者elements添加class,而後保持原有的class不變。
Good

<div class="block block--mod">...</div>
<div class="block block--size-big block--shadow-yes">...</div>

Bad

<div class="block--mod">...</div>

CSS

  • 使用modifier類名做爲選擇器 .block--hidden { }
  • 基於block級的modifier修改元素 .block--mod .block__elem { }
  • 元素修改器 .block__elem--mod { }

例子:
假設你的form Block由modifier:theme:"xmas" 以及simple:true 以及element:input 和submit,submit本身的modifier是disabled:true。
HTML:

<form class="form form--them-xmas form--simple"
    <input class="form__input" type="text" />
    <input class="form__submit form__submit--disabled" type="submit" />
</form>

CSS:

.form {}
.form--theme-xmas {}
.form--simple {}
.form__input {}
.form__submit {}
.form__submit--disabled {}
相關文章
相關標籤/搜索