React 样式方案
各有优缺点,选对场景最重要
1. CSS Modules
原理:构建工具把类名编译成哈希字符串。
/* Button.module.css */
.button {
background: blue;
}
import styles from './Button.module.css';
<button className={styles.button}>点我</button>
编译后:class="button_abc123"
优点
- 零运行时开销 — 纯 CSS,不影响 JS 包体积
- 不冲突 — 哈希命名,永远不担心类名重复
- 老牌稳定 — 兼容性好
缺点
- 动态样式写起来麻烦(需要配合
classnames 库)
为什么需要 classnames?
CSS Modules 的类名是编译后生成的,但实际项目中经常需要根据条件切换样式:
// ❌ 字符串拼接太繁琐
<button className={styles.button + (isActive ? ' ' + styles.active : '')}>
// ✅ 用 classnames 简化
import cx from 'classnames';
<button className={cx(styles.button, { [styles.active]: isActive })}>
classnames 可以优雅地合并多个类名,支持对象/数组/字符串写法,比字符串拼接干净多了。
2. CSS-in-JS (Styled-Components / Emotion)
原理:在 JS 里写 CSS,运行时生成 style 标签。
import styled from 'styled-components';
const Button = styled.button`
background: ${props => props.primary ? 'blue' : 'gray'};
`;
<Button primary>点我</Button>
优点
- 动态性强 — 直接读 props 生成样式
- 主题化方便 — 配合 ThemeProvider 轻松换肤
缺点
- 运行时开销 — 每次渲染要解析 CSS、生成哈希、插入 style 标签
- 包体积大 — 增加了库的大小
3. 原子化 CSS (Tailwind CSS)
原理:用工具类组合 UI。
<button className="flex items-center justify-center px-4 py-2 bg-blue-500 text-white rounded">
点我
</button>
优点
- 开发超快 — 不用在 HTML 和 CSS 之间来回切换
- 体积小 — 构建时 PurgeCSS 只保留用到的类
- 约束设计 — 强制统一间距、颜色
缺点
- HTML 类名很长,可读性差(VSCode 插件可以解决)
- 学习成本(要记一堆类名)
怎么选?
| 场景 | 推荐方案 |
|---|
| 大多数项目 | Tailwind CSS(效率王) |
| 组件库开发 | CSS-in-JS(方便换肤)或 CSS Modules(无依赖) |
| 性能敏感 | CSS Modules 或 Tailwind |
| 快速开发 | Tailwind |
总结
- CSS Modules:稳定、性能好,但动态样式麻烦
- CSS-in-JS:动态强、主题方便,但有运行时开销
- Tailwind:开发快、体积小,但类名长
按需选用,没有银弹。