css modules 在构建阶段将类名编译为唯一哈希(如 button_button__abc123),从源头物理消除命名冲突,不依赖 js 运行时,无 ssr/css 一致性风险,而 css-in-js 的类名生成发生在运行时,受加载顺序、实例隔离、hmr 等因素影响。

CSS Modules 在解决样式命名冲突这件事上,更直接、更确定、更轻量。它不靠运行时生成或 JS 逻辑兜底,而是在构建阶段就把类名变成唯一哈希值,冲突根本不会发生——不是“避免”,是“物理消除”。
为什么 CSS Modules 的命名冲突解决是编译时确定的
CSS Modules 的核心动作发生在构建阶段:所有 .button、.card 这类类名,都会被 css-loader 或 postcss-modules 替换为类似 Button_button__abc123 的唯一标识。这个过程不依赖 JS 执行,也不依赖组件挂载时机。
- 同一个文件里重复定义
.button,会被合并;不同文件里的.button,必然生成不同哈希,完全隔离 - 即使你 import 了十个模块,每个
styles.button指向的都是独立类名,不存在运行时覆盖或顺序问题 - 没有 JS 介入,也就没有 SSR 与 CSR 类名不一致的风险(CSS-in-JS 的
styled-components在服务端渲染时若未正确 hydrate,可能触发 FOUC 或样式错乱)
CSS-in-JS 的“无冲突”其实依赖运行时环境
CSS-in-JS 库(如 styled-components、Emotion)确实也生成唯一类名,但它是运行时动态注入的,这带来几个隐性条件:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 必须确保 JS 已加载并执行,否则样式不生效(纯 HTML 静态预览或 JS 报错时,组件会裸奔)
- 服务端渲染需额外配置(如
StyleSheetManager+extractCritical),漏配就导致首屏无样式 - 多个包共用同一 CSS-in-JS 实例时,若版本不一致或实例隔离失败,类名可能复用或冲突(尤其微前端场景)
- 热更新(HMR)下,某些库会保留旧样式规则,造成冗余甚至优先级错乱
容易被忽略的兼容性细节
很多人以为“用了 CSS-in-JS 就不用管命名”,但实际项目中常踩这些坑:
-
:global()在 CSS Modules 中是显式、可控、可审计的;而 CSS-in-JS 里想写全局样式(比如重置第三方组件),往往得靠createGlobalStyle或injectGlobal,一旦多处调用,顺序和作用域难追踪 - CSS Modules 支持
@import、@keyframes、伪类、媒体查询原样透出,无需适配;CSS-in-JS 对@keyframes、@font-face等规则的支持因库而异,Emotion 要用keyframes函数,styled-components 要用模板字符串嵌套,写法割裂 - 当需要对接设计系统或 UI 库(如 Ant Design)时,它们大多提供
.module.css版本,但极少提供完整的 styled-components 封装,强行迁移成本高
真正复杂的地方不在“能不能解决冲突”,而在于“冲突消失后,你还得面对什么”:CSS Modules 把问题锁死在构建阶段,换来的是可预测性;CSS-in-JS 把灵活性推到运行时,但也把不确定性一并带了进来。选哪个,取决于你愿不愿意为动态能力多扛一层运行时责任。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










