BEM规范是什么
BEM是 块(block) 、元素(element)、修饰符(modifier)的简写,由Yandex团队提出的一种css类命名约定。
- 连字符:块或元素的多单词之间的连接符号
__ 双下划线:块和元素的连接符号
-- 双连字符:作为块或元素的修饰符号
以这段html为例:
<div class="article">
<div class="article__body">
<div class="article__body-left">
<div class="article__body-logo">
<img class="icon" />
</div>
</div>
<button class="button button--primary"></button>
<button class="button button--default"></button>
</div>
<div class="article__footer article__footer--primary"></div>
</div>
block
block表示组件的顶级抽象,它仅仅作为一个边界,不应该在block上添加样式和修饰。
// 正确
.article{
&__body{
background: red;
}
}
// 错误
.article{
background: red;
}
element
element表示block下的元素,该元素依赖于块。
.article{
&__body{}
&__footer{}
}
如果元素下还嵌套子元素,均可用连接符 - 连接,这样可以清楚的知道该元素的父级。
像 .icon 、 .button 这种可以独立存在的子元素,避免创建不必要的父级。
举个例子,假如把 .button 命名为 .article__body-button ,后续的开发人员要在 ****.article__footer 里用 .article__body-button 的样式:
<div class="article">
<div class="article__body">
<div class="article__body-left">
<div class="article__body-logo">
<img class="icon" />
</div>
</div>
<button class="article__body-button button--primary"></button>
<button class="article__body-button button--default"></button>
</div>
<div class="article__footer article__footer--primary">
<!-- 假设这里要用到article__body-button的样式 -->
<button class="article__body-button"></button>
</div>
</div>
可以看到,.article__body-button 在 .article__footer 下,这会使代码变得混乱和不一致,应该避免这种情况的出现。
modifier
修饰符,改变块或元素的样式。
如 .button--primary、.article__footer--primary
BEM规范的优点
- 当想要创建新组件时,我们可以容易的知道哪些修饰符和子组件已存在
- 从html结构上,能快速知道块和元素、元素和嵌套元素间的依赖关系,如,我们用连接符
-表示元素下的嵌套 - 统一的命名方式,方便团队成员的阅读
总结
- block不要添加修饰符和样式
- element下,子元素均用连接符
-连接 - element下,没有后代的元素可用单个单词表示,方便复用
推荐用法:
<div class="article">
<div class="article__body">
<div class="article__body-left">
<div class="article__body-logo">
<img class="icon" />
</div>
</div>
<button class="button button--primary"></button>
<button class="button button--default"></button>
</div>
<div class="article__footer article__footer--primary"></div>
</div>
.article{
&__body{
&-left{}
&-logo{}
.icon{}
.button{
&--primary{}
&--default{}
}
}
&__footer{
&--primary{}
}
}