咱們知道,css使用中一個比較使人煩惱的問題,就是css沒有做用域可言,咱們寫了一個組件或者模塊以後,每每但願它們能夠四處複用,可是因爲css沒有做用域,咱們給樣式命名的時候都會很是當心,由於懼怕命名重複致使組件的樣式被覆蓋。因而,每一個新加入項目的開發者在開發相似已有的組件時,極可能就本身從新命名一份新的樣式表,以避免和現有的重複,那麼就會致使css文件像滾雪球同樣愈來愈大。css
如今市面上有許多旨在減小CSS代碼量,且方便程序員合做和維護CSS代碼的方案,例如OOCSS、SMACSS、SUITCSS,而BEM是其中最常被人提起的一個方案。html
BEM的本質其實只是一個css命名方案。前端
BEM is a highly useful, powerful and simple naming convention to make your front-end code easier to read and understand, easier to work with, easier to scale, more robust and explicit and a lot more strict.(BEM是一個很是有用,強大和簡單的命名規範,使您的前端代碼更容易閱讀和理解,更容易使用,更容易擴展,更強大和更明確,更嚴格。)git
以上是BEM官網的解釋,能夠知道它就是一個命名方案,那麼它的規範是怎樣的?爲何說它更容易閱讀也更容易擴展呢?咱們下面來看看BEM的具體命名規範。程序員
所謂BEM,實際上是三個單詞的縮寫:Block(模塊)、Element(元素)、Modifier(修飾符)。github
一個塊是一個獨立的實體,就像應用的一塊「積木」。一個塊既能夠是簡單的也能夠是複合的(包含其餘塊)。sass
命名規範:less
塊名稱能夠由拉丁字母,數字和短劃線組成。 如:.blockide
以下圖的搜索框和按鈕組成的組件就是一個塊。
性能
一個元素是塊的一部分,具備某種功能。元素是依賴上下文的:它們只有處於他們應該屬於的塊的上下文中時纔是有意義的。
下圖中的input和button都是元素。
命名規範:
元素名稱能夠包含拉丁字母,數字,破折號和下劃線。 CSS類名寫成塊名稱加上兩個下劃線加上元素名稱:.block__elem
修飾符是塊或元素上的標誌。這些標誌用來形容元素或塊的外觀、行爲或狀態。例如button、a標籤上的active狀態。
命名規範:
修飾符名稱能夠包含拉丁字母,數字,破折號和下劃線。 CSS類名寫成塊或元素的名稱加上兩個破折號:.block--mod或.block__elem--mod和.block--color-black。
假設您有一個帶有修飾符「theme:xmas」和「simple:true」的表單塊,而且表單塊帶有input和submit元素。submit元素帶有修飾符「disabled: true」,在未填充表單時禁止提交表單。
HTML
<form class="form form--theme-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 { }
從上面的實例中,咱們不難發現BEM有如下特色:
試想,BEM的命名規範這麼長,若是咱們本身手寫那麼長的類名,那非得累死不可。所以藉助一些如less、sass的預處理器來幫忙,能夠提高咱們的開發效率。
以less爲例,咱們可使用&符簡化咱們的代碼:
.form { width: 12rem; height: 6rem; &__input{ font-size: 16px; } &__submit{ background: blue; &--disabled{ background: gray; } } }
編譯後:
.form { width: 12rem; height: 6rem; } .form__input { font-size: 16px; } .form__submit { background: blue; } .form__submit--disabled { background: gray; }
1.命名並不是那麼死板
實際上,不少團隊在應用BEM的時候,都根據本身的業務做了必定的調整,好比Instagram團隊使用的駝峯式: .blockName-elementName--modifierName { /* ... / },還有單下劃線:.block-name_element-name--modifierName { / ... */ }。因此不用那麼嚴格遵照,可根據本身的須要來變化。
2.修飾器的寫法有可改進之處
有時候元素的狀態須要js來控制,此時遵循BEM規範沒有任何好處,好比激活狀態,BEM推薦的寫法是:
.block__element { display: none; } .block__element--active { display: block; }
這樣就須要咱們知道block__element的名稱,並且類名也會變得很長,並且active類的樣式也沒法複用,所以咱們能夠考慮用常規的操做增長例如.js-active或.is-active這樣的類名來控制。
.block__element { display: none; } .block__element.is-active { display: block; }
3.每一個block能夠單獨一個css
因爲BEM規範下產出的css獨立性高,所以能夠考慮每一個組件單獨一個css,當某個頁面須要某個組件時,是須要把這個組件的css @import 到頁面的css中便可。
/* page.css */ @import "form.css"; @import "slider.css"; .block__element { display: none; }
參考:
使用案例: