引言
在开发 React 应用时,我们常常会遇到这样的问题:多个组件中使用了相同类名,导致样式相互覆盖,最终渲染效果与预期不符。比如我们创建了两个按钮组件:Button
和 AnotherButton
,它们分别定义了自己的 .button
样式:
jsx
import { useState } from 'react'
import './App.css'
import Button from './components/Button'
import AnotherButton from './components/AnotherButton'
// 与import有关,谁在上面就先加载
function App() {
return (
<>
<Button/>
<AnotherButton/>
</>
)
}
export default App
jsx
// Button.jsx
<button className="button">Button</button>
// AnotherButton.jsx
<button className="button">AnotherButton</button>
css
/* button.css */
.button {
background-color: blue;
color: white;
padding: 10px 20px;
}
/* another-button.css */
.button {
background-color: red;
color:white;
padding: 10px 20px;
}
效果图:

我们发现一个问题 : 对应的 CSS 文件中,.button
分别定义了不同的背景色(一个蓝色,一个红色),但当我们运行项目时,发现两个按钮都显示一样的颜色。这是为什么?
问题出现:样式冲突
原因很简单:类名重复了 。浏览器会根据样式加载顺序,后面定义的样式覆盖前面的样式 。因此,AnotherButton
中的 .button
覆盖了 Button
中的样式,导致所有按钮都变成了红色。
这种样式冲突在大型项目中尤为常见,尤其是在多人协作 开发时,不同的开发者可能在不同的组件中使用了相同的类名,造成样式混乱,难以排查。
再修改一下App.jsx
:
jsx
import { useState } from 'react'
import './App.css'
// 修改顺序*******************
import AnotherButton from './components/AnotherButton'
import Button from './components/Button'
// 与import有关,谁在上面就先加载
function App() {
return (
<>
<Button/>
<AnotherButton/>
</>
)
}
export default App

我们并没修改组件放置的顺序,为什么会出现不一样的情况?
原因:大多数构建工具(如 Webpack、Vite)会按照 import 的顺序插入样式 (
import .. from '..'
)到最终的 CSS 文件或<style>
标签中。
解决方案:CSS 模块化
为了解决这个问题,我们可以使用 CSS 模块化(CSS Modules) 技术。CSS Modules 是一种 CSS 文件的模块化处理方式,它让每个 CSS 文件中的类名只在当前组件中有效,不会影响其他组件,也不会被其他组件的样式覆盖。
我们只需要将 CSS 文件命名为 *.module.css
的形式,例如:
text
button.module.css
another-button.module.css
然后在组件中导入它:
jsx
// Button.jsx
import styles from './button.module.css'
<button className={styles.button}>Button</button>
jsx
// AnotherButton.jsx
import styles from './another-button.module.css'
<button className={styles.button}>AnotherButton</button>
此时,虽然两个组件都使用了 .button
类名,但由于 CSS Modules 的处理机制,每个类名都会被编译成唯一的哈希值,如:

这样就实现了:
- 不干扰外部样式(样式封闭)
- 不被外部样式干扰(样式隔离)

CSS Modules 的优势
- 类名唯一性:构建时自动添加哈希值,确保类名全局唯一。
- 可读性不受影响 :开发时我们仍然使用
.button
这样的语义化类名,打包后才会被替换为哈希值。 - 模块化管理:每个组件的样式独立,易于维护,适合工程化开发。
- 构建工具支持:Vite、Webpack、React 等现代构建工具天然支持 CSS Modules。
结语
在组件开发中,类名冲突是一个常见但容易被忽视的问题。CSS 模块化通过自动哈希机制,为每个组件的样式提供了"隔离舱",让样式既不污染外界,也不受外界干扰。
它提升了项目的可维护性和稳定性,是现代前端工程化中不可或缺的一环。掌握 CSS Modules,是写出高质量组件的重要一步。