styled创建带逻辑的react组件并自动处理props和主题,css仅生成需手动挂载的哈希类名字符串;前者适合交互式ui单元,后者适合静态样式片段或第三方库集成。

styled 和 css 函数本质区别在哪
二者不是替代关系,而是分工不同:styled 用于创建带样式的 React 组件,css 仅生成可复用的 CSS 类名字符串(class name),必须手动挂载到元素上。
常见误用是以为 css 能直接返回样式对象或内联样式 —— 它返回的是类似 "css-1a2b3c" 的哈希类名,不是 { color: 'red' }。
-
styled.div返回一个组件,可直接 JSX 中使用:<button>Click</button> -
css返回字符串,需配合className使用:<div classname="{myCss}">…</div> -
css支持动态插值但不自动处理 props;如需响应 props 变化,得配合styled或手动传参重算
什么时候该用 styled,什么时候用 css
选 styled 当你写的是「有行为、可复用、带逻辑的 UI 单元」:按钮、卡片、输入框等。它天然支持 props 驱动样式、伪类、媒体查询嵌套,且组件名自带调试标识(DevTools 中显示 StyledButton)。
选 css 当你只需要「一段可共享的样式片段」:比如统一的阴影、过渡动画、工具类(sr-only)、或需要注入到第三方组件的 class(如 react-datepicker 的 calendarClassName)。
- 用
styled写按钮:支持disabled、variant、size等 props 直接控制样式 - 用
css提取transition:避免每个styled组件重复写transition: all 0.2s - 第三方库要求传 class 字符串时,只能用
css,不能用styled(后者返回组件)
动态样式写法差异与性能注意点
styled 中插值函数接收整个 props,适合复杂条件判断;css 插值函数只接收当前作用域变量,更轻量但也更受限。
const Button = styled.button`
background: ${props => props.primary ? '#007bff' : '#6c757d'};
`;
const hoverStyle = css`
&:hover {
transform: translateY(-1px);
}
`;
// ❌ 错误:hoverStyle 不知道 props
// ✅ 正确:在 styled 里组合
const FancyButton = styled(Button)`
${hoverStyle}
`;
-
styled的插值函数每次渲染都执行,若含复杂计算,建议 memo 化或提前计算好值 -
css插值函数只在定义时运行一次(除非你把它包进组件内部并依赖 props) - 两者都支持主题(ThemeContext),但
css需显式通过useTheme获取,styled自动注入
容易忽略的 SSR 和调试问题
服务端渲染(SSR)时,css 生成的类名必须和客户端一致,否则样式丢失。Emotion 默认启用 cache 复用,但若你在多个 entry 或模块中重复调用 css 创建相同样式,可能生成不同哈希 —— 尤其在 Webpack HMR 或多包开发中。
- 确保所有
css调用都在同一模块作用域,或用key显式固定缓存键:css({ key: 'shared-transition' }, ...) - DevTools 中
styled组件显示为真实组件名(可搜索),css生成的类名默认无语义(如css-abc123),可用label注释:css({ label: 'button-hover' }, ...) - 全局重置或字体加载等副作用,仍需用
Global组件或injectGlobal(已废弃,推荐Global)
最常被跳过的细节是:css 不会自动提取伪类或媒体查询的父级上下文 —— 它只是拼字符串。如果你把 css 结果直接塞进 style 属性,它就完全失效了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











