[译]跟着例子学 BEM 命名约定

原文:BEM by Example, by Nathan Rambeck.css

BEM 一个流行的类名约定标准,它的基本概念很简单,但对于新手而言,刚接触时也会碰到一些误区,本文将经过一系列例子来解释常见的使用误区。html

BEM(是 Block-Element-Modifier 的简写形式)是一个 CSS 类名的命名标准。如今已被普遍使用,用来编写易于阅读、理解和扩展的 CSS 代码。spa

为何是 BEM

使用 BEM 命名方式有以下三点好处:code

  1. 命名自己可以传达功能或目的
  2. 命名自己可以传达组件结构
  3. 它是由一系列低权重选择器组成的

BEM 的工做原理

使用 BEM 方式组织的类名由如下三部分组成:htm

  1. 块(Block):组件的最外层的祖先元素定义为块。
  2. 元素(Element):组件内部中的后代元素,多是一个多是多个。
  3. 修饰符(Modifier):表示块或元素的一个变体。

若是上面三部分所有使用,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 的目的之一是为了低权重和一致性。不要忽略后代元素的类名,不然你只能经过增长权重的方式为这些裸露的元素赋样式(下面代码里的 imgfigcap 就是例子)。不使用类名可能结构看上去更简洁,但却增长了将来出现级联问题的风险。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

若是你如今尚未开始使用 BEM,那我强烈建议你在下一个项目中使用它。它可能与你已有的书写习惯不一样,但我相信你很快就能看到使用它为项目带来的好处。

但愿上面的这些例子能帮助你避免,大多数人在第一次使用这种古怪的命名约定时所犯的一些常见错误。

(完)

相关文章
相关标签/搜索