BEM
一、BEM概要
什么是BEM命名法
BEM — Block Element Modifier 是一种帮助您在前端开发中创建可重用组件和代码共享的方法,由 Yandex 团队提出的一种前端 CSS 命名方法论。
它背后的想法是将用户界面划分为独立的块。这使得界面开发变得简单快捷,即使使用复杂的UI,它也允许重用现有代码而无需复制和粘贴。
二、BEM命名方法
BEM组成
BEM 类名最多包含三个部分。
- 块 Block:组件的最外层父元素定义为块。
- 元素 Elemnt:组件内部可以是一个或多个称为元素的子元素。
- 修饰符 Modifier:块或元素可能具有由修饰符表示的变体。
如果所有三个都用于一个名称,它将看起来像这样:
[block]__[element]--[modifier]
在简短的介绍之后,让我们看一些具体的例子。
BEM实例
没有元素或修饰符的组件
简单组件可能只使用单个元素,因此单个类将成为块。
<button class=”btn”></button>
<style>
.btn {}
</style>
具有修饰符的组件
组件可能具有变体。应使用修饰符类实现变体。
<!-- DO THIS -->
<button class="btn btn--secondary"></button>
<style>
.btn {
display: inline-block;
color: blue;
}
.btn--secondary {
color: green;
}
</style>
不要单独使用修饰符类。修饰符类旨在扩充而不是替换基类。
<!-- DON'T DO THIS -->
<button class="btn--secondary"></button>
<style>
.btn--secondary {
display: inline-block;
color: green;
}
</style>
包含元素的组件
更复杂的组件将具有子元素。每个需要设置样式的子元素都应包含一个命名类。
BEM背后的目的之一是保持低特异性和一致性。不要从 HTML 中的子元素中省略类名。这将迫使您使用具有更高特异性的选择器来设置组件内那些裸元素的样式(请参阅下面的 和 元素)。关闭这些课程可能更简洁,但您将来会增加级联问题的风险。BEM 的一个目标是让大多数选择器只使用单个类名。imgfigcaption
<!-- DO THIS -->
<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>
如果组件具有多个级别的子元素,请不要尝试在类名中表示每个级别。BEM不是为了传达结构深度。表示组件中子元素的 BEM 类名应仅包含基本/块名称和一个元素名称。在下面的示例中,请注意 BEM 的错误用法,而更合适。photo__caption__quotephoto__quote
<!-- DO THIS -->
<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>
<!-- DON'T DO THIS -->
<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>
带修饰符的元素
在某些情况下,您可能希望改变组件中的单个元素。在这些情况下,向元素而不是组件添加修饰符。我发现修改元素比修改整个组件要少得多,也用处不大。
<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>
基于组件修饰符设置元素样式
如果您发现自己以相同的方式一起修改同一组件的元素,请考虑将修饰符添加到组件的基部,并根据该修饰符调整每个子元素的样式。这将增加特异性,但它使修改组件变得更加简单。
<!-- DO THIS -->
<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>
<!-- DON'T DO THIS -->
<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 名称有意使用双下划线和双连字符,而不是使用单连字符来分隔块元素修饰符。原因是单个连字符可以用作单词分隔符。类名应该非常可读,因此除非缩写是普遍可识别的,否则缩写并不总是可取的。
<!-- 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>
三、BEM其它相关知识
BEM的特性
- 易用性:要使用 BEM,您只需使用 BEM 的命名约定。
- 模块化:独立的块和 CSS 选择器使您的代码可重用且模块化。
- 灵活:使用BEM,可以按照您喜欢的方式重构和配置方法和工具。
BEM好处
待更新
BEM的缺陷
待更新