css-in-js使样式成为react数据流一部分,支持基于props、state、theme的动态计算与响应式更新,避免class爆炸和stale style问题。

因为样式行为必须随组件状态实时响应,而纯CSS无法直接消费 props、state 或 theme 对象 —— 它只能监听有限的伪类或媒体查询,没法做 if、switch 或函数调用。
动态样式必须靠 JavaScript 运行时计算
比如一个按钮要根据 isLoading、variant、size 和当前主题色同时决定背景、边框、字体大小和禁用态表现。纯 CSS 只能靠一堆 class 切换(如 btn--loading、btn--primary-sm),但 class 组合爆炸后根本不可维护。
- CSS-in-JS 允许你直接写
background: ${props => props.isLoading ? '#ccc' : props.theme.colors.primary} - 所有分支逻辑都在一个表达式里,和组件 render 保持同步,无需手动管理 class 列表
- React 更新时自动重算样式,不会出现“state 已变但 class 没更新”的 stale style 问题
主题切换不是换 CSS 文件,而是重渲染样式规则
暗色模式切换不是加载另一套 dark.css,而是把新 theme 对象传给所有 styled 组件。纯 CSS 变量(:root { --color-bg: #111; })虽然能切,但无法实现条件分支:比如 border-color 在暗色下要随 variant 动态变化,而 CSS 变量本身不支持嵌套逻辑。
-
styled-components的ThemeProvider和useTheme让 theme 成为 React context,天然响应更新 - Emotion 的
css函数可直接在任意组件内使用theme,不依赖 styled 包装 - 注意:theme 对象不能是每次 render 都新建的对象,否则触发无效样式重生成
伪类与响应式需绑定组件级状态,而非 viewport
纯 CSS 媒体查询只认 window.innerWidth,但组件经常需要响应 isMobile(来自 props)、density(来自 context)或 expanded(来自本地 state)。这些都不是 DOM 属性,CSS 选不到。
- 你可以写
padding: ${props => props.density === 'compact' ? '4px' : '12px'},完全绕过媒体查询 -
&:hover和&:focus在 CSS-in-JS 中仍是声明式写法,但可以和 JS 状态组合:&:hover:not(:disabled) { ... } - 避免在样式函数里调用未 memo 的复杂计算(如
getComputedSize(props)),否则每次 render 都执行
真正容易被忽略的是:CSS-in-JS 的优势不在于“写起来爽”,而在于它让样式成为 React 数据流的一部分 —— 一旦脱离这个上下文(比如用 className 手动拼接 class 名),逻辑就断了,维护成本反而更高。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











