2026 年 CSS-in-JS 现状
CSS-in-JS 并未消亡——但开发者使用它的方式已发生根本性转变。如果你今天正在使用 React、Next.js 或基于组件的设计系统进行开发,问题不在于 CSS-in-JS 是否已死,而在于运行时模型是否仍然适合你的架构。
下面是对当前现状的客观审视。
关键要点
- CSS-in-JS 生态系统已分裂为两大阵营:运行时库(styled-components、Emotion)和零运行时工具(vanilla-extract、Panda CSS、StyleX)。
- React Server Components 和流式 SSR 使得运行时 CSS-in-JS 在现代 Next.js 架构中变得显著复杂。
- 零运行时工具在构建时提取样式,消除了大部分运行时样式开销与水合复杂性。
- 运行时 CSS-in-JS 仍适用于纯客户端应用、React Native,以及需要真正运行时主题切换的代码库。
- 对于 2026 年的新 React 或 Next.js 项目——尤其是重度使用 RSC 的项目——零运行时样式方案正日益成为默认选择。
核心分歧:运行时 vs 零运行时 CSS-in-JS
CSS-in-JS 生态系统已分化为两个截然不同的阵营。
运行时 CSS-in-JS——例如 styled-components 和 Emotion 等库——在渲染期间通过 JavaScript 生成并注入样式。这种方式在客户端渲染应用中表现良好,但也带来实实在在的代价:额外的 JavaScript 包体积、运行时样式插入,以及服务端渲染环境中的水合复杂性。
零运行时 CSS-in-JS——例如 vanilla-extract、Panda CSS 和 StyleX 等工具——在构建时提取样式并输出静态 CSS 文件。渲染时没有 JavaScript 在为样式工作。浏览器拿到的是一份纯粹的样式表。
性能差异在大规模和受限条件下最为显著。在中端移动设备和较慢的网络环境中,运行时样式插入会增加水合期间的主线程负担。零运行时工具基本上完全规避了这一问题。
React Server Components 如何改变了局面
React Server Components(RSC)和 Next.js App Router 不仅让运行时模型变慢,更让它变得显著复杂。
运行时 CSS-in-JS 依赖于在渲染过程中收集并注入样式。而 Server Components 在服务端运行,并不直接支持客户端运行时行为。结果就是:styled-components 和 Emotion 等库在搭配 App Router 使用时,通常需要 Client Component 边界、样式注册表(style registry)或专门的 SSR 集成层。
这并不会让运行时 CSS-in-JS 在现代 Next.js 应用中变得无法使用,但它确实削弱了 RSC 本应带来的部分架构简洁性和性能优势。官方的 Next.js CSS-in-JS 文档明确指出了这些限制和集成要求。
React 18 的流式 SSR 进一步加剧了这一问题。运行时样式插入与流式输出的 HTML 块之间会产生不顺畅的交互,增加了无样式内容闪烁(FOUC)和水合边界情况出现的风险。
零运行时 CSS-in-JS 则没有这种限制。在服务端开始渲染之前,样式就已经被编译为静态 CSS 文件。
React 19 还通过 <style> 组件 API 引入了对样式表优先级和去重的更好的原生支持,缓解了样式管理中长期存在的一些痛点——尽管这并不能让运行时 CSS-in-JS 在本质上变得 RSC 原生。
2026 年每种方案的适用场景
| 方案 | RSC 兼容性 | 运行时样式开销 | 最佳适用场景 |
|---|---|---|---|
| styled-components | ✅ 是,v6.3+ | 有 | 现有 styled-components 应用、重度客户端应用、受限场景下的 RSC |
| Emotion | ⚠️ 部分 | 有 | 基于 MUI 的设计系统、Client Components |
| vanilla-extract | ✅ 是 | 无 | TypeScript 优先的设计系统 |
| Panda CSS | ✅ 是 | 无 | 兼具 CSS-in-JS 开发体验与 RSC 支持 |
| StyleX | ✅ 是 | 无 | 大规模原子化 CSS |
| CSS Modules | ✅ 是 | 无 | 简单的作用域样式、任意规模团队 |
| Tailwind CSS | ✅ 是 | 无 | 工具类优先、快速开发 |
styled-components 仍被广泛部署——它存在于数百万个生产代码库中,短期内不会消失。但它已于 2025 年进入维护模式,许多重度使用 React Server Components 的新项目现在优先评估零运行时替代方案。
vanilla-extract 提供了样式生态中最强大的 TypeScript 集成之一。你在 .css.ts 文件中编写样式,享有完整的类型安全、编译期的设计令牌(design token)校验,以及零运行时开销。
Panda CSS 是传统 CSS-in-JS 在精神上最接近的继承者。编写体验与之前的熟悉感保持一致,而输出的是静态的原子化 CSS。
Discover how at OpenReplay.com.
运行时 CSS-in-JS 仍然适用的场景
不要为迁移而迁移。运行时 CSS-in-JS 仍然适用于以下情况:
- 你的应用仅客户端渲染,没有 SSR 或 RSC
- 你正在维护一个运行良好且未触及性能瓶颈的现有 Emotion 或 styled-components 代码库
- 你需要真正的运行时主题切换——基于页面加载后获取的用户数据动态改变样式
- 你在使用 React Native,其中 StyleSheet 模型才是惯用做法
迁移一个大型稳定代码库的成本通常难以被性能收益所证明,除非你正在主动采用 RSC,或遇到了可量化的渲染瓶颈。
结论
关于 CSS-in-JS 的争论已不再停留于阵营之争。运行时库并不是失败品——它们诞生之时解决了真实存在的问题。零运行时工具则化解了运行时库带来的诸多取舍。
如果你在 2026 年开始一个新的 React 或 Next.js 项目,更安全的默认选择正越来越倾向于静态样式方案:追求简洁可选 CSS Modules,追求工具类优先的快速开发可选 Tailwind,而若希望保留 CSS-in-JS 的人机工学体验同时避免运行时开销,则可选用 vanilla-extract 或 Panda CSS。
如果你在维护现有代码库,请只在有明确理由时逐步迁移——而不是因为生态系统向前演进了就盲目跟进。
常见问题
没有,styled-components 并未被废弃,但它已进入维护模式。该库仍在接收更新,在生产环境中依然稳定可用。然而,它在与 React Server Components 配合时存在已知限制,因此 2026 年许多新项目会优先评估 vanilla-extract 或 Panda CSS 等零运行时替代方案。
可以,但集成比静态 CSS 方案要复杂。实际使用中,这些库与 App Router 配合时通常需要 Client Component 边界、样式注册表或专门的 SSR 配置。两个库都能在现代 Next.js 应用中工作,但零运行时工具通常能更自然地契合 React Server Components 模型。
CSS Modules 使用纯 CSS 文件并配以局部作用域的类名,样式无需 JavaScript 语法。而零运行时 CSS-in-JS(如 vanilla-extract)允许你用 TypeScript 或 JavaScript 编写样式,然后在构建时提取出来。两者都输出静态 CSS,但零运行时工具提供了类型安全和可编程主题能力,这是 CSS Modules 无法企及的。
除非有明确理由,否则不必。当你正在采用 React Server Components、遇到可量化的性能瓶颈,或者无论如何都要进行大规模重构时,迁移才是合理的。对于运行良好、稳定的客户端渲染应用,迁移的工程成本通常难以换来与之相称的收益。
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..