原文:BEM by Example, by Nathan Rambeck.css
BEM 一個流行的類名約定標準,它的基本概念很簡單,但對於新手而言,剛接觸時也會碰到一些誤區,本文將經過一系列例子來解釋常見的使用誤區。html
BEM(是 Block-Element-Modifier 的簡寫形式)是一個 CSS 類名的命名標準。如今已被普遍使用,用來編寫易於閱讀、理解和擴展的 CSS 代碼。spa
使用 BEM 命名方式有以下三點好處:code
使用 BEM 方式組織的類名由如下三部分組成:htm
若是上面三部分所有使用,BEM 的書寫形式看起來是這樣的:element
[block]__[element]--[modifier]
get
通過簡短的介紹以後,咱們下面來看一些具體的例子。string
有些組件簡單到只用一個元素就能表達出來,這個單獨的類就是塊。spark
<button class="btn"></button>
<style> .btn {} </style>
複製代碼
組件可能會有變體。組件變體使用修飾符來實現。io
<!-- 這樣寫 -->
<button class="btn btn--secondary"></button>
<style> .btn { display: inline-block; color: blue; } .btn--secondary { color: green; } </style>
複製代碼
修飾符是配合基礎類使用的,不能單獨使用,修飾符中也不會包含基礎樣式。
<!-- 不要這樣寫 -->
<button class="btn--secondary"></button>
<style> .btn--secondary { display: inline-block; color: green; } </style>
複製代碼
較複雜的組件包含後代元素,每個須要賦予樣式的元素都應該有一個名稱。
使用 BEM 的目的之一是爲了低權重和一致性。不要忽略後代元素的類名,不然你只能經過增長權重的方式爲這些裸露的元素賦樣式(下面代碼裏的 img
和 figcap
就是例子)。不使用類名可能結構看上去更簡潔,但卻增長了將來出現級聯問題的風險。BEM 的一個目標是讓大多數選擇器只使用一個類名。
<!-- 這樣寫 -->
<figure class="photo">
<img class="photo__img" src="me.jpg">
<figcaption class="photo__caption">Look at me!</figcaption>
</figure>
<style> .photo { } /* 權重 10 */ .photo__img { } /* 權重 10 */ .photo__caption { } /* 權重 10 */ </style>
<!-- 不要這樣寫 -->
<figure class="photo">
<img src="me.jpg">
<figcaption>Look at me!</figcaption>
</figure>
<style> .photo { } /* 權重 10 */ .photo img { } /* 權重 11 */ .photo figcaption { } /* 權重 11 */ </style>
複製代碼
若是組件中包含多個層次的後代元素,不要試圖在類名中表現出每一層。BEM 不是爲了傳達結構深度。BEM 表達的是組件中的一個後代元素,類名是由塊和元素組成。下面的例子裏,.photo__caption__quote
不是正確的 BEM 寫法,.photo__quote
纔是。
<!-- 這樣寫 -->
<figure class="photo">
<img class="photo__img" src="me.jpg">
<figcaption class="photo__caption">
<blockquote class="photo__quote">
Look at me!
</blockquote>
</figcaption>
</figure>
<style> .photo { } .photo__img { } .photo__caption { } .photo__quote { } </style>
<!-- 不要這樣寫 -->
<figure class="photo">
<img class="photo__img" src="me.jpg">
<figcaption class="photo__caption">
<blockquote class="photo__caption__quote"> <!-- 類名中出現的後代元素不能多於一個 -->
Look at me!
</blockquote>
</figcaption>
</figure>
<style> .photo { } .photo__img { } .photo__caption { } .photo__caption__quote { } </style>
複製代碼
在某些狀況下,你可能但願修改組件中的某個元素的樣式。這時候,應該給元素而不是組件添加修飾符。固然,相比於修改整個組件,修改組件中某個元素的場景不太常見,用處也小。
<figure class="photo">
<img class="photo__img photo__img--framed" src="me.jpg">
<figcaption class="photo__caption photo__caption--large">Look at me!</figcaption>
</figure>
<style> .photo__img--framed { /* 增量樣式修改 */ } .photo__caption--large { /* 增量樣式修改 */ } </style>
複製代碼
若是你發現本身老是以相同的方式修改某個組件裏的多個元素,那麼能夠考慮將修飾符添加到組件的基類名上,並根據這個修飾符的含義,調整每一個後代元素的樣式。這種方式會增長選擇器權重,但讓修改組件樣式變得更簡單了。
<!-- 這樣寫 -->
<figure class="photo photo--highlighted">
<img class="photo__img" src="me.jpg">
<figcaption class="photo__caption">Look at me!</figcaption>
</figure>
<style> .photo--highlighted .photo__img { } .photo--highlighted .photo__caption { } </style>
<!-- 不要這樣寫 -->
<figure class="photo">
<img class="photo__img photo__img--highlighted" src="me.jpg">
<figcaption class="photo__caption photo__caption--highlighted">Look at me!</figcaption>
</figure>
<style> .photo__img--highlighted { } .photo__caption--highlighted { } </style>
複製代碼
BEM 名稱故意使用雙下劃線和雙連字符,來分隔塊-元素-修飾符。若是使用的名稱中包含多個單詞,那麼就可使用一個連字符鏈接這多個單詞。這樣的類名更加易讀,同時,應該儘可能避免使用縮寫,除非這個縮寫是你們廣泛知道的。
<!-- 這樣寫 -->
<div class="some-thesis some-thesis--fast-read">
<div class="some-thesis__some-element"></div>
</div>
<style> .some-thesis { } .some-thesis--fast-read { } .some-thesis__some-element { } </style>
<!-- 不要這樣寫 名稱讀起來很費勁 -->
<div class="somethesis somethesis--fastread">
<div class="somethesis__someelement"></div>
</div>
<style> .somethesis { } .somethesis--fastread { } .somethesis__someelement { } </style>
複製代碼
若是你如今尚未開始使用 BEM,那我強烈建議你在下一個項目中使用它。它可能與你已有的書寫習慣不一樣,但我相信你很快就能看到使用它爲項目帶來的好處。
但願上面的這些例子能幫助你避免,大多數人在第一次使用這種古怪的命名約定時所犯的一些常見錯誤。
(完)