什么是BEM
BEM是非常受欢迎的一个css class names的命名惯例。BEM最基本的概念是非常简单易懂的,但是对于BEM的新手他们还是会出现普通的错误,所以通过下面各种案例来解释。
BEM(Block(容器)-Element(元素)-Modifier(修饰符))它收到广泛的推崇,并且它对于写出更容易阅读、理解和衡量的css是非常有帮助的。
为什么用BEM
BEM命名提供了三个特别的优势
- 它传达了目的和功能。
- 它传达了组件的结构。
- 它设置了一致的相当低的样式选择器的特殊性。
它是如何工作的
它包括三个部分
- Block:最外边的父元素的组件部分被定义为block
- Element:向里面的一个或多个children组件部分叫做elements。
- Modifier:通过Modifier来表示任何一个block或元素有一个标志性的改变。
其用法如下:
[block]__[element]--[modifier]
详细案例
组成没有Elements或Modifiers
简单的组件仅仅只是用单个的元素并且只有一个class,这个class将成为block
<button class=”btn”></button>
<style>
.btn {}
</style>
组成只有一个Modifier
一个组件只有一个变化。这个变化应该被用于modifier(修饰性)class。比如下面这个button元素有一个颜色的变化。
<button class="btn btn--secondary"></button>
<style>
.btn {
display: inline-block;
color: blue;
}
.btn--secondary {
color: green;
}
</style>
不要独自设置modifier class。这个modifier class是为了记录其某个变换的,而不是代替最基本的class。
比如下面这个做法就是不推荐的
<button class="btn--secondary"></button>
<style>
.btn--secondary { display: inline-block; color: green; }
</style>
只有Elements的组件
更加复杂的thml组成会有很多的子元素。每一个子元素都需要命名一个class来给它添加样式。
之前说过,BEM优势之一是保持一个很低和一致的特殊性。不要忽略子元素的类名。否则它会迫使你使用一个元素选择器来给这些元素(可以看下面的img和figcaption元素)添加样式,那么会增加你的样式特殊性。
不用这些类名可能更加的言简意赅,但是在将来会增加一连串冲突的风险。
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>
<!-- 不推荐的写法 -->
<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>
如果你的组件嵌套了多个深层次的子元素,不要试着用紧接着的上一个元素的类名。BEM不是为了创造更深的结构。
一个BEM类名代表这个组件的子元素只包含最基本的或block名和一个元素名。
在下面的例子中,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">
<!-- never include more than one child element in a class name --> Look at me!
</blockquote>
</figcaption>
</figure>
<style>
.photo { }
.photo__img { }
.photo__caption { }
.photo__caption__quote { }
</style>
只用Element和Modifier
在一些情况中,你想要在这个组件中的一个元素有变化,可以给这个元素加上一个修饰来代替这个组件。
<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>
基于祖先元素修饰符给元素添加样式
如果你发现你的多个子元素都有相同的修饰,那么可以给祖先元素添加修饰符,然后给每一个子元素添加样式。虽然这样做,会增加你的样式的特殊性,但是会让你的组件写法更简单。
<!-- 推荐写法 -->
<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命名故意使用双下划线和双连字符来代替分隔符Block-Element-Modifier。原因是为了单个的连字符能被作为单词分隔符来使用。类名应该容易被读懂,所以缩略是不值得被推崇的,除非这个缩略是大家普遍认识的。
<!-- 推荐做法 -->
<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>
<!-- 不推荐写法 -->
// 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>
BEM使你开心
如果你之前没用过BEM,现在推荐可以在你的下一个项目尝试使用它。也许一开始会觉得和你之前的写法不同,但是我确信你将会你会看到它在你的项目里会提供或大或小的优势。
文章翻译自BEM by Example