Skip to content
On this page

BEM-来自于 Yandex 的 CSS 命名方法论

什么是 BEM 命名规范

Bem 是块block 、元素element 、修饰符modifier 的简写,由 Yandex 团队提出的一种前端 CSS 命名方法论

- 中划线:仅作为连字符使用,表示某个块或者某个子元素的多单词之间的连接记号

__ 双下划线:双下划线用来连接块和块的子元素

-- 双中划线:双中划线用来描述一个块或者块的子元素的一种状态

BEM 是一个简单又非常有用的命名约定。让你的前端代码更容易阅读和理解,更容易协作,更容易控制,更加健壮和明确,而且更加严密

BEM 命名模式

css
/* 代表了更高级别的抽象或组件 */
.block {
}
/* 使用 _ 来连接块或块的子元素的状态 */
.block--modifier {
}
/* 代表.block的后代,用于形成一个完整的 .block 的整体 */
.block__element {
}
/* 使用 _ 来连接块或块的子元素的状态 */
.block__element--modifier {
}
/* 代表了更高级别的抽象或组件 */
.block {
}
/* 使用 _ 来连接块或块的子元素的状态 */
.block--modifier {
}
/* 代表.block的后代,用于形成一个完整的 .block 的整体 */
.block__element {
}
/* 使用 _ 来连接块或块的子元素的状态 */
.block__element--modifier {
}

BEM 命名法的好处

BEM 的关键是,可以获得更多的描述和更加清晰的结构,从其名字可以知道某个标记的含义。于是,通过查看 HTML 代码中的 class 属性,就能知道元素之间的关联

常规命名法示例:

html
<div class="article">
  <div class="body">
    <button class="button-primary"></button>
    <button class="button-success"></button>
  </div>
</div>
<div class="article">
  <div class="body">
    <button class="button-primary"></button>
    <button class="button-success"></button>
  </div>
</div>

使用 BEM 命名方法的示例

html
<div class="article">
  <div class="article__body">
    <button class="article__button--primary"></button>
    <button class="article__button--success"></button>
  </div>
</div>
<div class="article">
  <div class="article__body">
    <button class="article__button--primary"></button>
    <button class="article__button--success"></button>
  </div>
</div>

通过 BEM 命名方式,模块层级关系简单清晰,而且 css 书写上也不必作过多的层级选择

如何利用好 BEM 这种命名法

什么时候使用 BEM 命名法

  • 使用 BEM 的诀窍是,你要知道什么时候哪些东西是应该写成 BEM 格式的

  • 并不是每个地方都应该使用 BEM 命名方式。当需要明确关联性的模块关系时,应当使用 BEM 格式

  • 比如只是一条公共的单独的样式,就没有使用 BEM 格式的意义

css
.mr-10 {
  margin-right: 10px;
}
.mr-10 {
  margin-right: 10px;
}

在 CSS 预处理器中使用 BEM 格式

  • BEM 的一个槽点是,命名方式长而难看,书写不雅。相比 BEM 格式带来的便利来说,我们应客观看待

  • 一般来说会使用通过 LESS/SASS 等预处理器语言来编写 CSS,利用其语言特性书写起来要简单很多

以 LESS 为例

less
.article {
  max-width: 1200px;

  &__body {
    padding: 20px;
  }

  &__button {
    padding: 5px 8px;

    &--primary {
      background: blue;
    }

    &--success {
      background: green;
    }
  }
}
.article {
  max-width: 1200px;

  &__body {
    padding: 20px;
  }

  &__button {
    padding: 5px 8px;

    &--primary {
      background: blue;
    }

    &--success {
      background: green;
    }
  }
}

BEM 快速创建类名的钩子函数

ts
export function useNameSpace(defaultBlock: string = "") {
  const globalBlock = defaultBlock;

  const b = (block?: string) => (block ? block : globalBlock);
  const be = (element: string, block?: string) => {
    block = block ? block : globalBlock;
    return `${block}__${element}`;
  };
  const bm = (modifier: string, block?: string) => {
    block = block ? block : globalBlock;
    return `${block}--${modifier}`;
  };
  const em = (element: string, modifier: string, block?: string) => {
    block = block ? block : globalBlock;
    return `${block}__${element}--${modifier}`;
  };
  const bem = (block: string, element: string, modifier: string) =>
    `${block}__${element}--${modifier}`;

  return {
    b,
    be,
    bem,
    bm,
    em,
  };
}
export function useNameSpace(defaultBlock: string = "") {
  const globalBlock = defaultBlock;

  const b = (block?: string) => (block ? block : globalBlock);
  const be = (element: string, block?: string) => {
    block = block ? block : globalBlock;
    return `${block}__${element}`;
  };
  const bm = (modifier: string, block?: string) => {
    block = block ? block : globalBlock;
    return `${block}--${modifier}`;
  };
  const em = (element: string, modifier: string, block?: string) => {
    block = block ? block : globalBlock;
    return `${block}__${element}--${modifier}`;
  };
  const bem = (block: string, element: string, modifier: string) =>
    `${block}__${element}--${modifier}`;

  return {
    b,
    be,
    bem,
    bm,
    em,
  };
}

相关参考

Released under the MIT License.