CSS Modules

CSS Modules 是一种基于构建工具的样式作用域方案,通过为类名生成唯一标识来实现组件级局部作用域。

#type / concept #status / growing #tech / dev / frontend #resource / css #resource / css-modules

[!info] related notes

CSS Modules

一句话定义

CSS Modules 是一种构建期样式隔离方案:开发者写普通 CSS,构建工具把类名编译成唯一名字,从而实现组件级局部作用域。

核心机制 / 工作原理

浏览器并不原生理解 .module.css

CSS Modules 的关键在于构建工具会在编译阶段做几件事:

  1. 读取模块 CSS 文件。
  2. 解析其中的类名。
  3. 为类名生成唯一哈希标识。
  4. 输出一份类名映射对象给 JavaScript / TypeScript 使用。

例如你写:

.title {
  color: red;
}

构建后可能变成:

.Article_title__3f9a2 {
  color: red;
}

同时在组件里拿到映射:

{
  title: "Article_title__3f9a2"
}

这意味着两个组件都可以写 .title,但最终生成的类名不同,因此不会互相污染。

最小例子 / 最小场景

/* Button.module.css */
.root {
  padding: 8px 16px;
  border-radius: 6px;
}

.primary {
  background: #1677ff;
  color: white;
}
import styles from './Button.module.css';

export function Button({ primary }) {
  return (
    <button className={`${styles.root} ${primary ? styles.primary : ''}`}>
      Click
    </button>
  );
}

这里的 rootprimary 在组件外不可直接复用其原始类名,这正是它的隔离边界。

边界与易混淆点

  • CSS Modules 解决的是类名冲突,不自动解决样式设计是否合理、组件是否拆得清楚。
  • 它仍然是 CSS,不会像 CSS-in-JS 一样天然把状态表达式写进样式定义里。
  • 当状态很多时,需要组合多个 class,复杂度会回到组件代码里。
  • 它偏向“组件私有样式”,跨组件共享时通常还需要额外的 design tokens、公共变量文件或基础样式层。
  • 它和 Sass/SCSS 常一起使用,例如 Button.module.scss,前者解决作用域,后者解决表达能力。
  • 它和 Vue scoped 都属于编译期隔离思路,但实现方式不同:
    • CSS Modules 主要通过唯一类名映射。
    • Vue scoped 主要通过给选择器追加唯一属性选择器。
创建于 2026/5/14 更新于 2026/5/27