BEM的讲解

215 阅读3分钟

BEM是什么

BEM(支持Block-Element-Modifier)是一种为CSS class 方便命名的标准。它因其易于阅读,理解,衡量的特性而被广泛引用于书写CSS当中。

为什么选择BEM

BEM命名提供了三个明显的好处

1.它表达了目的或者功能。

2.它表达了组件结构。

3.它设置了简单一致的特征样式选择器。

如何起效果的

一个BEM的Class命名包含三个部分

1.Block:一个组件最外面的父元素被定义为block。

2.Element:一个组件当中一个或多个子元素被定义为element。

3.Modifer:block或者element其中之一或许会有变化的属性叫做modifer。

三个部分如果都能用到命名当中,结果如下:

[block]__[element]--[modifier]

在简要的介绍后,让我们看看一些具体的例子。

范例

组件中没有Element和Modifier

简单的组件可能仅有单一的元素组成,因此它的命名就只有block

<button class=”btn”></button>

<style> 
    .btn {} 
</style>

组件中有Modifer

一个组件可能会有变量。这个变量需要有modifier的class生效。

<!-- DO THIS --> 
<button class="btn btn--secondary"></button> 
<style> 
.btn {
    display: inline-block;
    color: blue; } 
    .btn--secondary { 
    color: green; 
} </style>

不要单独使用class 的modifer。modifer旨在扩充而不是替代基础class。

<!-- DON'T DO THIS --> 
<button class="btn--secondary"></button> 

<style> 
    .btn--secondary { 
    display: inline-block;
    color: green; }
</style>

组件中有element

更复杂的组件会有子元素。每个子元素的被定义的样式需要被命名的class。 BEM设计背后中的目的之一是保证特征的简单和一致性。不要在你的HTML中的子元素中省略class names。对class 的命名将会强迫你基于组件中这些基本的元素来使用选择器来增加它们的特征性(见如下的imgfigcaption)。不写这些class可能会显得更加简洁,但是你会在未来增加层叠的风险。BEM的目标之一就是让选择者使用单一的class命名。

<!-- 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>

如果你的组件中的元素有几个不同深度的层级,不要试图把每一层的意义体现在class命名中。 BEM并不打算表示结构的深度。一个BEM的class命名一个组件中的子元素时,应只包括block/base 的名字和 其中之一的元素名字。例如:photo__caption__quote在BEM中是不规范的命名,而photo__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>

元素带modifer

在一些场景中,你需要在组件中的单一元素的不同变化。在这些场景中添加一个modifer而不是增加一个组件。我发现这样使用更好:

<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>

样式元素基于组件的modifer

如果您发现自己以相同的方式一起修改同一组件的元素,请考虑将修饰符添加到组件的基部,并根据该修饰符调整每个子元素的样式。这将增加特异性,但它使修改组件变得更加简单。

<!-- 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,我强烈建议您在下一个项目中使用它。它可能与你习惯的有所不同,但我相信你会很快看到它为大大小小的项目带来的好处。而且,希望这些示例将帮助您避免我们大多数人在第一次深入研究这个古怪的命名约定时所犯的一些常见错误。