css modules是最省心、零运行时开销的模块化方案,它在构建时将.button编译为唯一哈希类名(如.button_abc123),从源头物理消除命名冲突,仅对.module.css后缀文件生效,需通过import styles from './x.module.css'动态注入类名。

直接用 CSS Modules,它是目前最省心、零运行时开销、且构建工具原生支持的模块化方案。别在命名上反复纠结,也别靠 !important 硬压,冲突根源是全局作用域,不是类名不够长。
为什么 .button 写了两遍就互相覆盖
因为浏览器眼里所有 .button 都一样,加载顺序和选择器权重决定谁生效,和你写在哪无关。哪怕一个在 Button.module.css,一个在 global.css,只要没启用模块化,就全是全局的。
-
CSS Modules只对.module.css(或.module.scss等)后缀文件生效,普通.css文件照旧全局 - 它不改语法,只在构建时把
.button编译成类似.button_abc123这样的唯一类名 - JS 中必须通过
import styles from './Button.module.css'获取映射,直接写className="button"不起作用 - 第三方库的 CSS(如
element-plus/dist/index.css)无法自动转为 Modules,得用:global()显式透出需要全局生效的部分
如何让局部样式打赢全局样式
冲突常表现为:你写了 .btn { color: red },但页面还是蓝色——大概率是第三方库用了更重的选择器,比如 .el-button.el-button--primary(权重 0,0,2,0),而你的只是 0,0,1,0。
- 打开 DevTools 的 Styles 面板,看目标样式是否被划掉;点进去确认来源文件和完整 selector
- 不要加
!important,它会破坏后续 modifier(如btn--large)的覆盖逻辑 - 提升局部权重更可靠:在
.module.scss中用自嵌套&.btn { color: red },或前置父级类名.my-button .btn - 如果必须覆盖第三方样式,用
:global()写高权重规则,例如:global(.el-button) { color: red !important },但仅限兜底
没构建工具时怎么隔离样式
纯 HTML 或老项目无法配 CSS Modules,就得靠命名空间硬隔离,而不是堆 BEM 或改类名。
- 给根容器加唯一属性,如
<div data-scope="admin">...</div> - 所有业务样式都前置该属性:
[data-scope="admin"] .btn { ... },比div div .btn更可控 - BEM 命名本身不隔离,
header__nav和第三方header__nav依然能撞;只有真实 DOM 结构匹配 + 唯一 block 名才有效 - 避免用标签+类组合(如
button.btn),很多 UI 库动态加类或不用 button 标签,规则会失效
真正容易被忽略的是:CSS Modules 不解决结构穿透问题。比如父组件设了 div * { color: red },子组件再怎么模块化也挡不住——这种全局通配规则,得从源头删,不是换个方案就能绕开的。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











