CSS BEM 命名规范|组件化样式分层权威指南

一、核心认知

BEM 是一套命名约定,不是语法,全称:

  • B Block 块:独立、可复用的组件模块
  • E Element 元素:块内部从属节点,不能脱离块单独使用
  • M Modifier 修饰符:描述块 / 元素的状态、变体、外观差异

目标: 消除样式命名歧义、降低选择器权重、避免深层嵌套、方便团队协作维护。

分隔符约定(业界主流)

  • 块 __ 元素:双下划线 __
  • 块 / 元素 -- 修饰符:双短横线 --
  • 多单词使用单短横线 - 连接

✅ 格式模板

复制代码
block
block__element
block--modifier
block__element--modifier

二、逐部分拆解

1. Block|块

一个独立功能组件,自身有完整语义,可以单独复用。

命名:描述功能,不要描述样式

复制代码
/* ✅ 好:语义化 */
.card
button-group
nav-header

/* ❌ 差:描述外观 */
.red-box
big-title

块内部可以包含多个元素。

2. Element|元素

属于某个块的子节点,不能脱离父块单独使用 。 用 __ 和块连接。

复制代码
.card__title
.card__content
.card__footer

❌ 禁止链式多层元素:card__content__text 元素只允许一层从属,深层结构继续当作元素,不要无限嵌套。

3. Modifier|修饰符

用来标记状态、样式变体、尺寸。-- 连接块或者元素。

复制代码
/* 块的修饰符 */
.card--dark
.card--borderless

/* 元素的修饰符 */
.card__title--primary
.card__title--small

修饰符不单独存在,必须依附在块 / 元素上。 修饰符只追加差异化样式,不要重写全部样式。

三、标准示例

HTML

复制代码
<div class="card card--dark">
  <h3 class="card__title card__title--primary">标题</h3>
  <div class="card__desc">描述文本</div>
</div>

CSS

复制代码
/* 基础块 */
.card {
  padding: 16px;
  border-radius: 8px;
}
/* 块修饰符 */
.card--dark {
  background: #1d2129;
  color: #fff;
}
/* 块内元素 */
.card__title {
  font-size: 18px;
  margin-bottom: 8px;
}
/* 元素修饰符 */
.card__title--primary {
  color: #409eff;
}
.card__desc {
  font-size: 14px;
  color: #666;
}

四、搭配预处理器(Less / SCSS)写法

复制代码
.card {
  padding: 16px;
  &--dark {
    background: #1d2129;
  }
  &__title {
    font-size: 18px;
    &--primary {
      color: #409eff;
    }
  }
}

注意:嵌套只是语法糖,编译出来依然是标准 BEM 类名,不会生成高权重后代选择器。

五、关键规则 & 避坑

  1. 不要用层级选择器 ❌ .card .title {} 容易权重混乱,优先用 BEM 类名

  2. 元素不能跨块 nav__card-title 错误,card 是独立块,应该 card__title

  3. 修饰符只做增量样式 不要把基础样式全部写在修饰符内

  4. 命名看语义,不看 DOM 结构 DOM 嵌套很深,类名依然保持一层 block__element

  5. 通用工具类,不属于 BEM 间距、文字对齐这类工具类单独抽离,不和 BEM 混在一起

mt-12 是工具类,不属于 BEM 体系。

六、适用场景与边界

✅ 适合:中大型后台项目、组件库、团队协作项目、长期维护页面 ❌ 没必要:简单 Demo、一次性活动页、页面极其简单的场景

BEM 不是强制标准,是权衡方案: 小项目写起来略长,但换来极高可维护性。

七、和其他命名方案对比

  • 原生随意命名:简短,极易冲突、难维护
  • BEM:类名长,语义清晰,权重扁平,适合团队
  • CSS Module:编译哈希,解决冲突,但可读性差,不方便直接覆盖调试

八、工程落地规范

  1. 统一分隔符,项目内不要混用多种 BEM 变体
  2. 多单词使用短横线:search-form__input-wrap
  3. 状态优先用修饰符,少用 is-xxx 状态类(团队可统一约定)
  4. 公共通用组件,块名全局唯一,避免跨页面重名冲突
相关推荐
进击的明明1 小时前
前端开发中的 BEM 国际命名规范:让 CSS 不再"打架"
前端·css·html
deli0071 小时前
中文在网址里为什么变成 E4B8AD?URL 编码 22 组用例实测
前端
羲云1 小时前
MOSS-Image 开源后爆火:5B 生图模型真正值得关注的,是可控排版
前端
BreezeJiang1 小时前
闭包和 useState 是两个知识点?你可能只学了半条作用域链
前端·面试
2601_958352901 小时前
一款模块通吃15类语音产品?AN-93如何实现录音笔、门禁、IPC的快速适配
前端·人工智能·嵌入式硬件·回声消除·降噪处理
子兮曰1 小时前
Bun v1.4.4 实测:2,025 个文件,bun fmt 2.6 秒跑完
前端·后端·bun
Liudef061 小时前
用 DeepSeek Search API 做一个干净的单文件搜索页面(附完整源码)
前端·人工智能·工具·搜索·deepseek
忆挽篱笙歌2 小时前
进程替换函数与shenll命令行解释器
前端·javascript·算法
计算机魔术师2 小时前
砸了2200亿美元还是不够用,AWS说2027年也卖完了
前端