惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

U
Unit 42
T
The Blog of Author Tim Ferriss
H
Help Net Security
博客园 - 叶小钗
云风的 BLOG
云风的 BLOG
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
D
DataBreaches.Net
博客园 - 聂微东
A
About on SuperTechFans
大猫的无限游戏
大猫的无限游戏
P
Proofpoint News Feed
Martin Fowler
Martin Fowler
博客园 - 【当耐特】
S
SegmentFault 最新的问题
Blog — PlanetScale
Blog — PlanetScale
酷 壳 – CoolShell
酷 壳 – CoolShell
G
Google Developers Blog
I
InfoQ
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
GbyAI
GbyAI
B
Blog
Engineering at Meta
Engineering at Meta
V
V2EX
Hugging Face - Blog
Hugging Face - Blog

博客园 - 箫笛

Tkinter - Entry 输入框组件 Tkinter - Button 组件 Tkinter - Label 组件 Tkinter - tk 变量 Tkinter - 事件与绑定 Tkinter - 几何管理器 Tkinter - 核心概念 Tkinter - 快速开始 Tkinter - 介绍 Python 编程 - 条件表达式 Python 编程 - 星号下划线参数释义 shell 编程 - shell 脚本的交互方式 Python insall - macOS 系统安装python的几种方式 Miniconda - Python 环境管理工具 Tkinter - Python GUI 开发 Python 编程 - 下划线命名的区别 Python 编程 - 元类编程 Python 编程 - 多重继承与MRO Python 编程 - 描述符协议 Python 编程 - 类型注解 Python 编程 - 生成器表达式 Python 编程 - 集合 Python 编程 - 装饰器 Python 编程 - 闭包 Python 编程 - 列表推导式 Python 编程 - 函数式编程 Python 编程 - lambda 函数 Python 编程 - 文件操作 Python 编程 - 输入与输出 Python 编程 - 面向对象编程
React15 - React CSS Modules BEM命名实践
箫笛 · 2026-03-22 · via 博客园 - 箫笛

在 React 项目中使用 CSS Modules 并结合 BEM 命名规范时,你遇到的“对象名称不支持 -”问题,是因为 JavaScript 对象属性名中不能直接包含连字符,但可以通过 方括号语法 来访问。以下是几种常见且推荐的实践方式:


1. 使用方括号语法访问带连字符的类名

这是最直接的方法,保持 BEM 类名的原始风格(如 block__element--modifier)。

/* Button.module.css */
.button {
  /* 基础样式 */
}
.button__icon {
  /* 元素样式 */
}
.button--primary {
  /* 修饰符样式 */
}
// Button.jsx
import styles from "./Button.module.css";

function Button({ primary, children }) {
  return (
    <button
      className={`
        ${styles.button}
        ${primary ? styles["button--primary"] : ""}
      `}
    >
      <span className={styles["button__icon"]}>✨</span>
      {children}
    </button>
  );
}

优点:完全保留 BEM 的可读性,符合团队规范。
缺点:每次访问都需要方括号,略显繁琐,组合多个类时可能需要借助工具。


2. 改用驼峰命名 + CSS Modules 转换

CSS Modules 默认支持驼峰命名,你可以将 BEM 风格转换为驼峰形式,然后直接用点号访问。这种方法更接近常规的对象属性访问。

/* Button.module.css */
.button {
  /* ... */
}
.buttonIcon {
  /* ... */
}
.buttonPrimary {
  /* ... */
}
// Button.jsx
import styles from "./Button.module.css";

function Button({ primary, children }) {
  return (
    <button
      className={`${styles.button} ${primary ? styles.buttonPrimary : ""}`}
    >
      <span className={styles.buttonIcon}>✨</span>
      {children}
    </button>
  );
}

优点:书写简洁,无需方括号,IDE 自动补全友好。
缺点:与 BEM 原始命名习惯略有差异,需要团队约定转换规则(例如 block__element 变为 blockElementblock--modifier 变为 blockModifier)。


3. 使用工具库简化类名组合

推荐使用 clsxclassnames 来动态组合类名,尤其适合条件判断较多的情况。

npm install clsx
import clsx from "clsx";
import styles from "./Button.module.css";

function Button({ primary, children }) {
  return (
    <button
      className={clsx(styles.button, primary && styles["button--primary"])}
    >
      <span className={styles["button__icon"]}>✨</span>
      {children}
    </button>
  );
}

clsx 还支持对象语法,更简洁:

className={clsx(styles.button, {
  [styles['button--primary']]: primary,
})}

4. 结合 CSS Modules 的 composes 复用样式

如果 BEM 修饰符需要继承基础样式,可以利用 CSS Modules 的 composes 特性,在 CSS 层面完成复用,减少 JS 中的逻辑。

/* Button.module.css */
.button {
  /* 基础样式 */
}
.button--primary {
  composes: button;
  /* 覆盖或新增样式 */
}

然后在 JS 中只需要一个类名:

<button className={primary ? styles["button--primary"] : styles.button}>
  {children}
</button>

总结

方式 适用场景
方括号语法 希望完全保留 BEM 原始命名,团队规范明确
驼峰命名 追求书写便捷、自动补全,可调整命名规范
工具库(clsx) 需要大量条件类名,代码更清晰、可维护
composes 修饰符依赖基础样式,希望减少 JS 条件判断

你可以根据团队习惯和项目复杂度选择一种或混合使用。无论哪种方式,CSS Modules 都能有效隔离样式,结合 BEM 则能保证样式命名清晰、可维护。