Skip to content

命名约定

一致的命名约定是代码可读性和可维护性的基石。在 HTML 开发中,class 命名直接影响 CSS 选择器和 JavaScript DOM 操作的效率。本节将详细介绍三种主流 CSS class 命名方法论(BEM、OOCSS、SMACSS)、id 命名规范、文件命名规范,帮助团队建立统一的命名体系。

前置知识

阅读本节前,建议先了解:缩进与格式化

为什么命名约定重要

  • 可读性:清晰的命名让代码自解释
  • 可维护性:统一的命名降低理解和修改成本
  • 可扩展性:好的命名规范支持项目规模的扩大
  • 协作效率:团队成员能快速理解代码结构

BEM 命名法

BEM(Block Element Modifier)是最流行的 CSS 命名方法论。

BEM 三个组成部分

组成部分说明命名规则示例
Block(块)独立的功能组件.block.card.nav
Element(元素)块的组成部分.block__element.card__title.nav__link
Modifier(修饰符)块或元素的变体.block--modifier.card--featured.nav--dark

BEM 示例

html
<!-- Block: 独立的用户卡片组件 -->
<div class="user-card user-card--featured">
  <!-- Element: 卡片的组成部分 -->
  <img class="user-card__avatar" src="avatar.jpg" alt="用户头像" />
  <h3 class="user-card__name">张三</h3>
  <p class="user-card__bio">前端工程师</p>

  <!-- Modifier: 修饰符表示变体 -->
  <div class="user-card__stats user-card__stats--expanded">
    <span class="user-card__stat">128 篇文章</span>
    <span class="user-card__stat">256 粉丝</span>
  </div>

  <!-- 块级修饰符 -->
  <button class="btn btn--primary user-card__follow-btn">
    关注
  </button>
</div>
html
<!-- 导航栏 BEM 示例 -->
<nav class="nav nav--dark">
  <div class="nav__logo">
    <a href="/" class="nav__link nav__link--logo">Logo</a>
  </div>
  <ul class="nav__menu">
    <li class="nav__item">
      <a href="/" class="nav__link nav__link--active">首页</a>
    </li>
    <li class="nav__item">
      <a href="/about" class="nav__link">关于</a>
    </li>
  </ul>
  <button class="nav__toggle nav__toggle--open" aria-label="打开菜单">
    <span class="nav__icon"></span>
  </button>
</nav>

OOCSS 命名法

OOCSS(Object-Oriented CSS)强调结构和皮肤分离。

核心原则

原则说明示例
结构与皮肤分离布局和视觉样式分开.btn + .btn-primary
容器与内容分离组件不依赖父容器.card 可在任何容器中使用
html
<!-- 结构 -->
<div class="media">
  <img class="media__img" src="avatar.jpg" alt="头像" />
  <div class="media__body">
    <h3 class="media__title">标题</h3>
    <p class="media__desc">描述内容</p>
  </div>
</div>

<!-- 皮肤(可复用的视觉样式) -->
<div class="card card--shadow card--rounded">
  <div class="card__header card__header--dark">
    <h2 class="card__title">标题</h2>
  </div>
  <div class="card__body">
    <p>内容</p>
  </div>
</div>

SMACSS 命名法

SMACSS(Scalable and Modular Architecture for CSS)将样式分为五类。

五大分类

类别前缀说明示例
Base基础元素样式h1abody
Layoutl-layout-页面布局.l-header.l-sidebar
Module可复用组件.card.nav
Stateis-s-状态变体.is-active.is-hidden
Themetheme-主题样式.theme-dark.theme-light
html
<!-- SMACSS 示例 -->
<div class="l-wrapper">
  <header class="l-header">
    <nav class="nav is-expanded">
      <ul class="nav__list">
        <li class="nav__item is-active">
          <a href="/" class="nav__link">首页</a>
        </li>
      </ul>
    </nav>
  </header>

  <main class="l-content">
    <div class="card is-featured">
      <h2 class="card__title">标题</h2>
      <p class="card__body">内容</p>
    </div>
  </main>
</div>

命名规范对照

class 命名规则

规则推荐不推荐
使用小写.product-card.ProductCard
连字符分隔.nav-item.navItem.nav_item
避免缩写.navigation.nav(除非团队约定)
语义化命名.article-title.title-red-big
避免使用 ID 作为样式.header(class)#header(id)

id 命名规则

html
<!-- id 命名:用于 JavaScript 钩子和锚点 -->
<div id="main-content"></div>
<div id="user-profile"></div>
<div id="order-form"></div>

<!-- id 使用驼峰式或连字符式 -->
<div id="mainContent"></div>
<div id="main-content"></div>

JavaScript 钩子命名

html
<!-- 使用 data 属性标记 JS 钩子,避免依赖 class -->
<button class="btn btn-primary" data-js="submit-form">
  提交
</button>

<div class="dropdown" data-js="user-menu">
  ...
</div>

<!-- JavaScript 选择 -->
// 推荐:使用 data 属性
document.querySelector('[data-js="submit-form"]')

// 不推荐:使用 class
document.querySelector('.btn-primary')  // 如果 class 改变就失效

文件命名规范

文件类型命名规则示例
HTML 页面小写连字符product-detail.html
CSS 文件小写连字符main-navigation.css
图片文件小写连字符+描述hero-banner-home.jpg
JavaScript小写连字符或驼峰product-slider.js
字体文件小写连字符noto-sans-regular.woff2
项目目录结构示例:
├── index.html
├── product-detail.html
├── css/
│   ├── base.css
│   ├── layout.css
│   ├── components/
│   │   ├── card.css
│   │   ├── navigation.css
│   │   └── button.css
│   └── main.css
├── js/
│   ├── main.js
│   ├── navigation.js
│   └── product-slider.js
└── images/
    ├── logo.svg
    ├── hero-banner.jpg
    └── icons/
        ├── arrow-right.svg
        └── search.svg

实战示例:统一的命名风格

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>BEM 命名示例</title>
</head>
<body>
  <!-- 页面布局:SMACSS l- 前缀 -->
  <div class="l-page">
    <header class="l-header">
      <!-- 组件:BEM 命名 -->
      <nav class="nav" aria-label="主导航">
        <div class="nav__brand">
          <a href="/" class="nav__logo">品牌</a>
        </div>
        <ul class="nav__list">
          <li class="nav__item is-active">
            <a href="/" class="nav__link">首页</a>
          </li>
          <li class="nav__item">
            <a href="/products" class="nav__link">产品</a>
          </li>
        </ul>
        <button
          class="nav__toggle"
          data-js="nav-toggle"
          aria-label="切换菜单"
          aria-expanded="false"
        >
          <span class="nav__icon"></span>
        </button>
      </nav>
    </header>

    <main class="l-main">
      <div class="l-container">
        <!-- 产品卡片组件 -->
        <article class="card card--featured">
          <img
            class="card__image"
            src="product.jpg"
            alt="产品描述"
            loading="lazy"
          >
          <div class="card__content">
            <h2 class="card__title">产品名称</h2>
            <p class="card__description">产品简介</p>
            <div class="card__footer">
              <span class="card__price">¥299.00</span>
              <button
                class="btn btn--primary card__action"
                data-js="add-to-cart"
                data-product-id="12345"
              >
                加入购物车
              </button>
            </div>
          </div>
        </article>
      </div>
    </main>

    <footer class="l-footer">
      <div class="l-container">
        <p class="l-copyright">&copy; 2024 品牌</p>
      </div>
    </footer>
  </div>
</body>
</html>

注意事项

  1. 选择一种方法论:BEM、OOCSS、SMACSS 各有优势,选择最适合团队的
  2. 保持一致性:一旦选择就坚持使用,不要混用不同风格
  3. 避免过度嵌套:BEM 中避免超过两层的 __ 嵌套
  4. JS 钩子与样式分离:使用 data-js 属性标记 JS 交互元素
  5. 命名要有语义:避免使用颜色、位置等无语义的名称

最佳实践

  • 推荐使用 BEM 命名法
  • 使用连字符 - 分隔单词
  • 语义化命名,避免描述性名称
  • JS 钩子使用 data-* 属性
  • 文件命名使用小写连字符
  • 在项目中编写命名规范文档
  • 使用 stylelint 检查命名一致性

下一节

继续学习:注释规范

参考链接