正在加载,请稍候…

CSS-in-JS vs Tailwind vs CSS Modules:2026年样式方案选型指南

对比 CSS-in-JS、Tailwind CSS v4 和 CSS Modules 在包体积、运行时开销、开发体验及 SSR 兼容性上的差异,提供 2026

CSS-in-JS vs Tailwind vs CSS Modules:2026年样式方案选型指南

样式之战:2026 年的格局

前端样式领域在多年的碎片化后已趋于稳定。CSS-in-JS(styled-components、Emotion)、Tailwind CSS 和 CSS Modules 各有明确的适用场景。本文抛开炒作,基于真实的性能数据和开发体验权衡,为你提供决策框架。

CSS-in-JS vs Tailwind vs CSS Modules:2026年样式方案选型指南 插图

三大竞争者

CSS-in-JS(Emotion、styled-components)

CSS-in-JS 在运行时(或通过静态提取在构建时)从 JavaScript 生成 CSS。它在 2018–2022 年间是主流范式。

// Emotion — 样式与组件共存
import { css } from '@emotion/react'
import styled from '@emotion/styled'

const buttonBase = css`
  display: inline-flex;
  align-items: center;
  padding: 8px 16px;
  border-radius: 6px;
  font-weight: 500;
  cursor: pointer;
`

const PrimaryButton = styled.button`
  ${buttonBase}
  background: ${props => props.theme.colors.primary};
  color: white;

  &:hover {
    background: ${props => props.theme.colors.primaryHover};
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
`

优势

  • 基于 props 的条件样式自然且类型安全
  • 自动作用域隔离,无类名冲突
  • 与 TypeScript 结合的主题系统符合人体工程学
  • 样式与组件逻辑共存

劣势

  • 运行时开销:CSS 在渲染时解析并注入
  • JavaScript 包体积较大(styled-components:约 16KB gzipped)
  • 动态样式在每次渲染时都会重新计算
  • 在 RSC(React Server Components)中性能较差——它们仅在客户端运行

零运行时 CSS-in-JS(Linaria、vanilla-extract、Panda CSS)

下一代演进:CSS-in-JS 语法,但在构建时静态提取:

// vanilla-extract — 类型安全的 CSS,零运行时
import { style, createTheme, styleVariants } from '@vanilla-extract/css'

export const [themeClass, vars] = createTheme({
  color: {
    primary: '#0070f3',
    primaryHover: '#0051b5',
  },
  space: {
    sm: '8px',
    md: '16px',
  },
})

export const button = style({
  display: 'inline-flex',
  alignItems: 'center',
  padding: `${vars.space.sm} ${vars.space.md}`,
  borderRadius: '6px',
  fontWeight: 500,
  cursor: 'pointer',
})

export const buttonVariants = styleVariants({
  primary: {
    background: vars.color.primary,
    color: 'white',
    ':hover': { background: vars.color.primaryHover },
  },
  secondary: {
    background: 'transparent',
    border: `1px solid ${vars.color.primary}`,
    color: vars.color.primary,
  },
})

零运行时、完整的 TypeScript 推断和静态 CSS 输出。两全其美——但构建复杂度更高。

Tailwind CSS v4

Tailwind v4(2024 年发布)带来了重大变化:纯 CSS 配置(不再需要 tailwind.config.js)、原生 CSS 变量以及使用 Rust 编写的 Oxide 引擎带来的极速构建。

/* tailwind.css — v4 配置在 CSS 中 */
@import "tailwindcss";

@theme {
  --color-primary: oklch(55% 0.2 265);
  --color-primary-hover: oklch(45% 0.2 265);
  --font-sans: 'Inter', system-ui, sans-serif;
  --radius-md: 6px;
}
// 使用 Tailwind 工具类的组件
function Button({ variant = 'primary', children }: ButtonProps) {
  return (
    <button className={cn(
      'inline-flex items-center px-4 py-2 rounded-md font-medium cursor-pointer',
      'transition-colors duration-150',
      variant === 'primary' && 'bg-primary text-white hover:bg-primary-hover',
      variant === 'secondary' && 'bg-transparent border border-primary text-primary hover:bg-primary/10',
    )}>
      {children}
    </button>
  )
}

优势

  • 零运行时开销——生产环境为纯 CSS
  • 极小的 CSS 包体积,完美的 tree shaking(仅使用到的工具类)
  • 优秀的 IDE 支持(Tailwind IntelliSense)
  • 无需离开 HTML 即可实现一致的设计系统
  • v4 Oxide 引擎:构建速度提升 5 倍

劣势

  • 类名字符串冗长,尤其是包含多个条件样式时
  • 逻辑与样式混合在 className prop 中
  • 不常用工具类的学习曲线
  • 重构时需要查找所有类名使用处

CSS-in-JS vs Tailwind vs CSS Modules:2026年样式方案选型指南 插图

CSS Modules

CSS Modules 提供局部作用域的 CSS,且零 JavaScript 开销:

/* Button.module.css */
.button {
  display: inline-flex;
  align-items: center;
  padding: 8px 16px;
  border-radius: 6px;
  font-weight: 500;
  cursor: pointer;
}

.primary {
  background: var(--color-primary);
  color: white;
}

.primary:hover {
  background: var(--color-primary-hover);
}

.secondary {
  background: transparent;
  border: 1px solid var(--color-primary);
  color: var(--color-primary);
}
import styles from './Button.module.css'
import clsx from 'clsx'

function Button({ variant = 'primary', children }: ButtonProps) {
  return (
    <button className={clsx(styles.button, styles[variant])}>
      {children}
    </button>
  )
}

优势

  • 零运行时,零包体积开销
  • 标准 CSS——所有 CSS 特性均可使用
  • 优秀的浏览器 DevTools 体验
  • 适用于所有环境,包括 SSR/RSC

劣势

  • 没有内置的主题系统
  • 难以与组件逻辑共存
  • 动态样式需要 CSS 自定义属性或类名拼接

性能对比

方案 JS 包体积 CSS 包体积 运行时开销 SSR/RSC 开发体验
styled-components +16KB 0(注入) 有限 优秀
Emotion +11KB 0(注入) 中等 有限 优秀
vanilla-extract ~0KB 提取 完整 良好
Tailwind v4 0 极小 完整 优秀
CSS Modules 0 标准 完整 良好

真实包体积影响

在一个生产环境仪表盘应用(Next.js 15)上测量:

styled-components

  • JS:+16.3KB gzipped
  • LCP:2.4s
  • TBT:180ms(样式注入阻塞主线程)

vanilla-extract

  • JS:+0.5KB(SSR 水合运行时)
  • LCP:1.9s
  • TBT:40ms

Tailwind v4

  • JS:0KB
  • CSS:12KB gzipped(仅使用到的工具类)
  • LCP:1.7s
  • TBT:20ms

决策框架

CSS-in-JS vs Tailwind vs CSS Modules:2026年样式方案选型指南 插图

选择 CSS-in-JS(Emotion/styled-components)当:

  • 团队拥有强大的 JavaScript 能力,偏好 JS 优先的开发方式
  • 设计系统需要复杂的动态主题(暗色模式、用户可自定义主题)
  • 开发纯客户端 SPA,SSR 不是问题
  • 已在项目中大量使用,迁移成本超过收益

选择零运行时 CSS-in-JS(vanilla-extract、Panda CSS)当:

  • 希望获得 CSS-in-JS 的开发体验且零性能成本
  • TypeScript 优先的设计系统是首要目标
  • 团队能接受额外的构建工具复杂度

选择 Tailwind v4 当:

  • 启动新项目——它现在是务实默认选择
  • 团队包含设计师和开发者(工具类可读性强)
  • 性能和包体积是优先考虑因素
  • 使用 React Server Components 或其他 SSR 密集型架构

选择 CSS Modules 当:

  • 团队偏好编写真正的 CSS
  • 需要集成现有的大型 CSS 代码库
  • 需要对输出 CSS 有最大控制权
  • 在非 React 环境中工作

Tailwind v4 迁移说明

/* v3:JavaScript 配置 */
/* tailwind.config.js: theme: { extend: { colors: { primary: '#0070f3' } } } */

/* v4:CSS 配置 */
@theme {
  --color-primary: #0070f3;
}

/* v3 任意值仍然有效 */
.element {
  @apply text-[14px] leading-[1.6];
}

/* v4:新的 oklch 色彩空间支持 */
@theme {
  --color-brand: oklch(65% 0.18 250);
}

结论

在 2026 年,Tailwind v4 是新项目的务实默认选择。其 v4 重新设计解决了主要批评:配置现在在 CSS 中,构建速度前所未有地快,设计令牌系统也是一流的。

对于具有复杂主题需求的设计系统,vanilla-extract 提供了最佳的 TypeScript 集成且零运行时成本。老牌 CSS-in-JS(styled-components、Emotion)在零运行时替代方案出现并拥有可比的开发体验后,已失去性能优势。

CSS Modules 仍然是那些偏好编写真正 CSS 并希望最大简单性的团队的绝佳选择。如有疑问,选择你的团队会乐于长期维护的方案。