CSS Modules适合结构稳定、复用率高、交互简单的基础组件;Styled Components更适合需动态props插值、主题切换或频繁状态变化的场景。

CSS Modules 适合结构稳定、复用率高、交互简单的基础组件;Styled Components 更适合需要动态 props 插值、主题切换或频繁状态变化的场景。
什么时候该用 CSS Modules
它解决的是“类名不冲突”和“样式只作用于当前组件”这两个最基础的问题。如果你的项目里 Button、Input、Card 这类组件结构固定、样式变化少,且团队习惯写传统 CSS,CSS Modules 是更轻量、零运行时开销的选择。
- 必须用
.module.css后缀,否则import './Button.css'会全局污染 - TypeScript 项目需配
@types/css-modules或声明declare module '*.module.css',否则styles.xxx报类型错误 - 无法在 CSS 文件里读取
props,hover/active 状态得靠拼接 className:className={`${styles.base} ${isActive ? styles.active : ''}` - 不支持
@import非.module.css文件,否则破坏作用域隔离
什么时候该用 Styled Components
它不是编译时注入 CSS,而是每次组件渲染都执行一次模板字符串解析 + 哈希生成 + 样式注入。这意味着 styled.button 是一个运行时函数调用,适合需要强动态能力的场景。
- 支持直接在样式中使用
${props => props.color},但组件高频重渲染(比如动画按钮)时会重复执行插值逻辑 - 服务端渲染必须配
ServerStyleSheet或 Next.js 中加"use client"+createGlobalStyle,否则首屏无样式或样式重复注入 - 支持主题(
ThemeProvider)、伪类(&:hover)、媒体查询、嵌套语法,写法接近 SCSS - 打包体积略增(含运行时库),但开发体验更统一:样式即组件,无需额外 class 命名管理
别忽略构建与协作成本
选型不是只看功能,还要看团队实际落地能力。CSS Modules 对构建配置要求低,Modern.js / Vite 默认支持;Styled Components 需要确保 babel-plugin-styled-components 正确启用,否则生成的 class 名不带哈希前缀,调试困难。
立即学习“前端免费学习笔记(深入)”;
- 组件库对外发布时,CSS Modules 要求使用者有
css-loader;Styled Components 只需import组件,对使用者更友好 - 如果设计系统大量依赖 JS 变量(如颜色 token、断点配置),用 Styled Components 直接引用 JS 模块比维护一套
_variables.scss更可控 - 多人协作时,CSS Modules 的样式分散在多个文件,容易遗漏状态类;Styled Components 的样式逻辑集中,但容易把复杂条件塞进模板字符串里,反而难读
真正卡住人的往往不是“哪个更好”,而是“是否真能统一落地”。比如一个中后台项目,Button 组件需要根据 size、variant、loading 三重组合生成不同样式——这时候硬用 CSS Modules 拼 className,很快就会失控;而 Styled Components 写成 background: ${p => theme[p.variant]?.bg},反而清晰。但反过来,如果只是静态文档站,CSS Modules 就够了,没必要引入 runtime 开销。


















