CSS常用命名法:BEM国际命名规范

190 阅读3分钟

前言

在大型前端项目中,CSS的维护和管理一直是一个重要课题。为了使用CSS的开发更加规范,目前有很多流行的命名方法尝试在选择器命名上解决以下问题:

  • 减少大型项目中CSS占用的空间
  • 提高程序员间的协作效率
  • 简化CSS代码库的维护工作
  • 理清CSS的继承关系
  • 提高代码的可读性和可维护性
  • 避免样式冲突和污染

本文将对BEM(Block Element Modifier)命名规范进行深入介绍,并通过实战案例进行详细剖析

BEM(Block,Element,Modifier)

关于BEM

新手小白在写CSS的时候一定在命名上有很多困扰。我们都知道命名需要做到“见名知义”,但是如果组件层级关系和样式一多,就会带来命名相同、关系不清楚等的问题,又很苦恼。了解了BEM这个规范你将变得清晰明了。

什么是BEM?

BEM (Block, Element, Modifier)是由俄罗斯重要门户网站Yandex(类似于百度、谷歌等)的开发团队提出的一种CSS命名方法论。

来自BEM官方网站 (getbem.com)对BEM的定义:

BEM —— is a methodology that helps you to create reusable components and code sharing in front‑end development.

BEM —— 是一种帮助您在前端开发中创建可重用组件和代码共享的方法。

现在有许多国际大型企业都在使用BEM开发网页,除了在BEM官网中罗列的JetBrains,国内还有微信也在使用这一CSS命名方法。

BEM的核心思想

BEM的核心思想是 将页面拆分成一个个独立的富有语义的块(blocks)。 学习BEM主要就是学习它的命名层级命名约定

命名层级

BEM命名包含三个核心概念:

  1. Block(区块)

    • 独立的、可复用的组件
    • 可以包含其他Block
    • 例如:header、menu、form等
  2. Element(元素)

    • Block的组成部分
    • 不能脱离Block独立存在
    • 例如:menu__item、form__input等
  3. Modifier(修饰符)

    • 定义Block或Element的外观、状态或行为
    • 例如:button--primary、menu__item--active等

命名约定

BEM的命名规范非常严格,具体如下:

  1. Block命名

    • 使用小写字母
    • 单词之间用单短线(-)连接
    • 例如:headermenuform
  2. Element命名

    • 以Block名称为前缀
    • 使用双下划线(__)连接
    • 例如:header__logomenu__item
  3. Modifier命名

    • 以Block或Element名称为前缀
    • 使用双连字符(--)连接
    • 例如:button--primarymenu__item--active

BEM 实战

WeUI组件预览页面

这是一个微信WeUI中Button组件的预览页面,你也可以点击访问 WeUI组件预览-Button 一同领略其源码中的BEM命名法

但这个页面源码中,只参考了BEM的命名层级,其命名约定采用了团队内部的法则,与BEM不完全相同

为了大家能够对原始的BEM命名规范有深刻的了解,本文将会重新编写完全遵守BEM的代码来完成这个页面。

image.png

这个页面结构很简单,我们可以先为整个页面划分好布局: 定义整个页面命名为pageBlock,而下面的按钮和中间的操作可划分为Block下的Element,可以定义为page__hd和page__bd。 代码为:

<body>
 <!-- block -->
    <div class="page"> 
        <!-- element -->
        <div class="page__hd"></div>
        <div class="page__bd"></div> 
    </div>
</body>

image.png

其中page__hd内的Button和按钮属于page内的内容,所以我们可以用page__title和page__desc来描述。 代码为:
<body>
 <!-- block -->
    <div class="page"> 
        <!-- element -->
        <div class="page__hd">
            <div class="page__title"></div>
            <div class="page__desc"></div>
        </div>
        <div class="page__bd"></div> 
    </div>
</body>

image.png

按钮部分代码为:

                <!-- 主要按钮 -->
                <a href="#" class="button button--primary button--loading">主要操作</a>
                <a href="#" class="button button--primary button--disabled">主要操作</a>     
                <!-- 默认按钮 -->
                <a href="#" class="button button--default">次要操作</a>
                <a href="#" class="button button--default button--loading">次要操作</a>
                <a href="#" class="button button--default button--disabled">次要操作</a> 
                <!-- 警告按钮 -->
                <a href="#" class="button button--warn">警示操作</a>
                <a href="#" class="button button--warn button--loading">警示操作</a>
                <a href="#" class="button button--warn button--disabled">警示操作</a>

给出的demo: