React 里怎么写样式
How to use styles in React
一句话:五种, 各有明确的取舍。
| 方式 | 好处 | 代价 |
|---|---|---|
| 普通 CSS / SCSS 文件 | 零成本、能用全部 CSS 特性 | 类名全局,会冲突 |
| CSS Modules | 类名自动加哈希,天然隔离 | 动态样式要配 CSS 变量 |
行内 style | 动态值最直接 | 没有伪类、媒体查询、动画; 每次渲染新对象 |
| CSS-in-JS(styled-components) | 能用 props 决定样式,作用域天然隔离 | 运行时开销,SSR 要额外配置 |
| 原子化(Tailwind) | 不用起类名,产物体积可控 | JSX 里类名很长,团队要统一约定 |
「动态样式」的推荐做法—— 这是加分点:用 CSS 变量而不是行内 style。 把变量写在行内, 真正的样式规则还在 CSS 文件里 —— 这样既能动态,又保留伪类和媒体查询。本站的深色模式就是这么做的(切 data-theme 属性, CSS 变量整套换)。
会追问:「行内 style 为什么影响性能?」—— 每次渲染都创建新对象, 会破坏子组件的 memo; 而且它不能被浏览器按规则缓存。要用就 useMemo 稳住。
In one line: five ways, each with a clear trade-off.
| Approach | Upside | Cost |
|---|---|---|
| Plain CSS / SCSS files | Free, and every CSS feature is available | Class names are global, so they collide |
| CSS Modules | Hashed class names, isolated by default | Dynamic styles need CSS variables |
Inline style | The most direct way to use a dynamic value | No pseudo-classes, media queries or animations; a new object every render |
| CSS-in-JS (styled-components) | props can drive the styles, and scoping needs no extra work | Runtime cost, and SSR needs extra setup |
| Atomic (Tailwind) | No naming, and the output size stays under control | Very long class strings in JSX, and the team needs conventions |
The recommended way to do dynamic styles — this is the bonus point: use a CSS variable, not an inline style. Put only the variable inline and leave the actual rule in the CSS file — you get the dynamic value and keep pseudo-classes and media queries. That is how this site’s dark mode works (flip the data-theme attribute and the whole set of CSS variables swaps).
Follow-up: “Why do inline styles hurt performance?” — every render creates a new object, which breaks memo on the child, and the browser cannot cache it as a rule. If you must use one, stabilise it with useMemo.