css类命名规范-BEM

314 阅读1分钟

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规范的优点

  1. 当想要创建新组件时,我们可以容易的知道哪些修饰符和子组件已存在
  2. 从html结构上,能快速知道块和元素、元素和嵌套元素间的依赖关系,如,我们用连接符 - 表示元素下的嵌套
  3. 统一的命名方式,方便团队成员的阅读

总结

  • 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{}
  }
}