深入浅出BEM命名规范:微信WEUI框架的命名之道

72 阅读6分钟

深入浅出BEM命名规范:微信WEUI框架的命名之道

在前端开发的世界里,CSS命名就像城市中的路标——清晰明确的命名让团队协作畅通无阻,混乱的命名则会让项目陷入"堵车"状态。今天,我们就来解密大厂都在用的BEM命名规范,以微信WEUI框架为例,探索前端工程的命名艺术!

为什么需要命名规范?🚧

想象一下:当你加入一个新项目,看到这样的CSS代码:

.button { ... }
.btn { ... }
.red-button { ... }

你是不是会疑惑:

  • 这些类名之间有什么关系?
  • 什么时候用.button,什么时候用.btn
  • 这个.red-button是全局样式还是局部样式?

命名冲突样式污染维护困难正是缺乏规范的前端项目的通病。而BEM规范就是为解决这些问题而生的!

BEM规范核心概念 🧩

1. Block(块)—— 构建页面的乐高积木

Block是独立且有意义的界面组件,可以理解为页面中的"乐高积木块"。

在WEUI框架中:

/* 页面块 */
.weui-page { ... }

/* 按钮块 */
.weui-btn { ... }

/* 表单块 */
.weui-form { ... }

命名规则项目代号 + 区块的作用或职责

  • weui- 是微信UI的项目代号
  • page/btn/form 表示区块的功能

2. Element(元素)—— 块的组成部分

Element是Block的组成部分,不能脱离Block独立存在

在WEUI框架中:

<header class="weui-page__header">
  <h1 class="weui-page__title">Button</h1>
  <p class="weui-page__desc">按钮</p>
</header>

命名规则Block名称 + __ + 元素名称

  • __header:页面头部
  • __title:标题元素
  • __desc:描述元素

Block与Element的关系就像身体与四肢*

3. Modifier(修饰符)—— 组件的百变形态

Modifier用于表示Block或Element的状态或变体

在WEUI框架中:

<a class="weui-btn weui-btn_primary">主要按钮</a>
<a class="weui-btn weui-btn_default">次要按钮</a>

命名规则Block/Element名称 + _ + 状态描述

  • _primary:主要状态
  • _default:默认状态
  • _disabled:禁用状态

WEUI框架中的BEM实践 🛠️

让我们通过一个完整的WEUI页面组件,看看BEM如何实际应用:

<!DOCTYPE html>
<html>
<head>
  <!-- 省略meta标签 -->
  <title>WEUI Button UI 设计</title>
  <link rel="stylesheet" href="index.css">
</head>
<body>
  <!-- Block: 页面容器 -->
  <div class="weui-page">
    
    <!-- Element: 页面头部 -->
    <header class="weui-page__header">
      <h1 class="weui-page__title">Button</h1>
      <p class="weui-page__desc">按钮组件展示</p>
    </header>
    
    <!-- Element: 页面主体 -->
    <main class="weui-page__body">
      <div class="button-sp-area">
        <!-- Block + Modifier: 按钮及其状态 -->
        <a class="weui-btn weui-btn_primary">主要操作</a>
        <a class="weui-btn weui-btn_default">次要操作</a>
      </div>
      
      <!-- Block: 单元格组件 -->
      <div class="weui-cells">
        <h3 class="weui-cells__title">个人信息</h3>
        
        <!-- Block: 单个单元格 -->
        <div class="weui-cell">
          <!-- Element: 单元格各部分 -->
          <div class="weui-cell__hd">
            <img src="avatar.png" alt="头像">
          </div>
          <div class="weui-cell__bd">
            <p>张三</p>
          </div>
          <div class="weui-cell__ft">
            编辑
          </div>
        </div>
      </div>
    </main>
  </div>
</body>
</html>

对应的CSS实现:

/* Block: 页面容器 */
.weui-page {
  padding: 18px;
  background-color: #f5f5f5;
}

/* Element: 页面头部 */
.weui-page__header {
  padding: 40px 0;
  text-align: center;
}

/* Element: 页面标题 */
.weui-page__title {
  font-size: 24px;
  font-weight: bold;
  margin-bottom: 8px;
}

/* Element: 页面描述 */
.weui-page__desc {
  font-size: 14px;
  color: #888;
}

/* Block: 按钮 */
.weui-btn {
  display: block;
  padding: 12px 24px;
  border-radius: 4px;
  text-align: center;
  font-size: 16px;
  margin-bottom: 15px;
}

/* Modifier: 主要按钮 */
.weui-btn_primary {
  background-color: #07C160;
  color: white;
}

/* Modifier: 默认按钮 */
.weui-btn_default {
  background-color: #F2F2F2;
  color: #333;
}

/* Block: 单元格容器 */
.weui-cells {
  background: white;
  border-radius: 8px;
  overflow: hidden;
  margin-top: 20px;
}

/* Element: 单元格标题 */
.weui-cells__title {
  padding: 16px;
  font-size: 18px;
  font-weight: bold;
  border-bottom: 1px solid #eee;
}

/* Block: 单个单元格 */
.weui-cell {
  display: flex;
  align-items: center;
  padding: 16px;
}

/* Element: 单元格头部 */
.weui-cell__hd {
  margin-right: 15px;
}

/* Element: 单元格主体 */
.weui-cell__bd {
  flex: 1;
}

/* Element: 单元格尾部 */
.weui-cell__ft {
  color: #888;
}

image.png

使用BEM规范的WEUI按钮和单元格组件

BEM的黄金法则 ✨

  1. 禁止跨层级依赖

    /* 错误示范 */
    .weui-page .header { ... }
    
    /* 正确示范 */
    .weui-page__header { ... }
    
  2. 避免嵌套过深

    /* 不推荐 */
    .weui-page__header__title__text { ... }
    
    /* 推荐 */
    .weui-page__title { ... }
    
  3. 保持单一职责

    /* 不推荐 - 混合了块和元素 */
    .weui-page-header { ... }
    
    /* 推荐 */
    .weui-page__header { ... }
    
  4. 语义化命名

    /* 不推荐 - 基于样式的命名 */
    .weui-btn-green { ... }
    
    /* 推荐 - 基于功能的命名 */
    .weui-btn_success { ... }
    

为什么大厂都爱BEM?🏆

  1. 自解释的代码结构:看到类名就知道组件结构和关系
  2. 避免样式冲突:层级扁平化,减少嵌套带来的权重问题
  3. 组件化开发:每个Block都是独立组件,便于复用
  4. 团队协作友好:新人也能快速理解项目结构
  5. 可扩展性强:新增状态或变体只需添加Modifier

图:BEM规范让团队协作像交响乐一样和谐

image.png

实战技巧:从WEUI中学到的经验 🚀

1. 项目前缀的重要性

WEUI使用weui-前缀,有效避免与业务代码冲突:

/* 框架样式 */
.weui-btn { ... }

/* 业务样式 */
.user-btn { ... }

2. 原子化Modifier设计

WEUI的按钮状态设计:

/* 尺寸修改器 */
.weui-btn_mini { font-size: 12px; }

/* 状态修改器 */
.weui-btn_disabled { opacity: 0.6; }

/* 类型修改器 */
.weui-btn_warn { background-color: #E64340; }

3. 元素命名一致性

WEUI中的单元格元素:

.weui-cell__hd /* 头部(head)区域 */
.weui-cell__bd /* 主体(body)区域 */
.weui-cell__ft /* 尾部(foot)区域 */

这种一致的命名规则贯穿整个框架,降低了学习成本。

如何开始使用BEM?📌

  1. 从小组件开始:从按钮、卡片等简单组件入手
  2. 制定团队规范:统一前缀、命名风格等规则
  3. 使用Sass/Less辅助
    .weui-page {
      padding: 18px;
      
      &__header {
        padding: 40px 0;
      }
      
      &__title {
        font-size: 24px;
      }
    }
    
  4. 代码审查:在PR中检查BEM规范的执行
  5. 文档化:建立团队的BEM命名文档

结语:让命名成为艺术 🎨

BEM不仅仅是命名规范,更是一种前端工程化思维。通过微信WEUI框架的实践,我们看到了一套好的命名规范如何:

  • 提升代码可读性:类名即文档
  • 增强组件复用性:像搭积木一样构建页面
  • 降低维护成本:即使半年后也能快速理解

"任何傻瓜都能写出计算机可以理解的代码。好的程序员能写出人类可以理解的代码。" —— Martin Fowler

从今天开始,让你的CSS类名会说话!💬 当你下次写.weui-page__header时,记住:你不仅在写样式,更在构建一个可维护、可扩展的前端工程体系。

BEM小测验:你能为下面的结构设计BEM类名吗?

<!-- 一个用户卡片组件 -->
<div>
  <div><img src="avatar.jpg"></div>
  <div>
    <h3>用户名</h3>
    <p>用户描述</p>
  </div>
  <div>2023-10-01</div>
</div>

把你的答案写在评论区吧!👇 我们会在下篇文章中公布最佳实践方案~


想了解更多WEUI设计规范?访问官方文档:WEUI Design

延伸阅读

  1. BEM官方文档
  2. 微信WEUI框架源码分析
  3. 大型CSS项目的维护之道

希望这篇文章能帮助你掌握BEM精髓,提升前端工程化能力!如果觉得有帮助,请点赞⭐️收藏~