BEM(全称Block-Element-Modifier)是一种CSS类的命名约定,它具有相当广泛的应用而且让我们码出来的CSS能够更加容易的阅读,理解以及度量方面非常有用。
为什么使用BEM命名
BEM命名法提供以下三点明确的好处:
- 它传递目标或者功能
- 它传递内容结构
- 它为样式选择器设置了一致的低水平特征
BEM命名法是如何工作的
一个BEM 类名包含了至多三部分
- Block: 元素的外层父元素被定义为block
- Element:组件内部的一个或多个孩子被定义为元素
- Modifier:一个块或者一个元素会由修饰语来指出变化
如果所有三个部分在命名中被使用他会看起来像这样:
[block]__[element]--[modifier]
在这简短的介绍之后,让我们看一些特殊的例子
举例
没有Elements或者Modifier组成的命名
简单的命名可能只有一个单一元素名因此一个block就能构成一个class
<button class="btn"></button>
<style>
.btn {}
</style>
命名之中modifier组成
组件会有形态的变化,这个变化需被class的modifier指出
<button class="btn btn--secondary"></button>
<style>
.btn {
display: inline-block;
color: blue;
}
.btn--secondary {
color: green;
}
</style>
不要去单独使用元素形态去命名class,元素的形态是去增加而不是替代原本的class命名
<!-- DON'T DO THIS -->
<button class="btn--secondary"></button>
<style>
.btn--secondary {
display: inline-block;
color: green;
}
</style>
命名包含Elements
更多复杂的组件都会包含子元素,每个子元素想被装饰需要包含一个被命名的类名
BEM命名法其中的一个目标就是保持特征低等且一致,不要从HTML的子元素中忽略类名,那会强迫你使用增强特征的选择器去修饰在 BEM命名法其中的一个目标就是保持特征低等且一致,不要从HTML的子元素中忽略类名,那会强迫你使用增强特殊性的选择器去设置裸元素的样式,放弃这样的类会更加简洁,但在将来会增加层叠问题的风险。BEM命名法的其中一个目标就是让大多数的选择器使用一个简单的类名。
<figure class="photo">
<img class="photo__img" src="me.jpg">
<figcaption class="photo__caption">Look at me!</figcaption>
</figure>
<style>
.photo { } /* Specificity of 10 */
.photo__img { } /* Specificity of 10 */
.photo__caption { } /* Specificity of 10 */
</style>
<!-- DON'T DO THIS -->
<figure class="photo">
<img src="me.jpg">
<figcaption>Look at me!</figcaption>
</figure>
<style>
.photo { } /* Specificity of 10 */
.photo img { } /* Specificity of 11 */
.photo figcaption { } /* Specificity of 11 */
</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 {
/* incremental style changes */
}
.photo__caption--large {
/* incremental style changes */
}
</style>
多个单词的命名
BEM命名法考虑使用双下划线以及双连字符来取代单一的下划线以及连字符去隔开Block-Element-Modifier,原因是单一连字符可用作为单词的分隔符。类的命名是需要非常强的可读性,所以略缩词并不每次都期望被使用除非这个略缩词是被普遍承认的。
<!-- DO THIS -->
<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>
<!-- DON'T DO THIS -->
// These class names are harder to read
<div class="somethesis somethesis--fastread">
<div class="somethesis__someelement"></div>
</div>
<style>
.somethesis { }
.somethesis--fastread { }
.somethesis__someelement { }
</style>