styled-components:用 JS 写 CSS,React 样式这块它干了十年
styled-components:用 JS 写 CSS,React 样式这块它干了十年
styled-components 在 GitHub 上已经拿到 41K Star 了。
2016 年出来的,专门解决 React 里写 CSS 的各种别扭。到现在十年了,依然是 React 生态里用得最多的 CSS-in-JS 方案之一。

1、 到底解决了什么问题
React 组件化开发有个老毛病:样式怎么管。
写全局 CSS,类名冲突是家常便饭,改个按钮颜色得全局搜一遍生怕漏掉。CSS Modules 解决了作用域问题,但写起来还是要在 JS 和 CSS 文件之间来回跳。BEM 命名法能用,但那一长串类名写多了谁都烦。
styled-components 的思路很直接:把 CSS 直接写在 JS 组件里,每个组件自带样式,自动生成唯一的类名,不用操心命名冲突,不用维护单独的样式文件。
2、 长什么样
用法很直观。用 tagged template literal 定义一个组件,里面写 CSS:
const Button = styled.button`
background: palevioletred;
color: white;
padding: 0.5em 1em;
border-radius: 4px;
`;
这个 Button 就是一个带样式的 React 组件,直接当 JSX 用就行。
想根据 props 改样式?插个函数进去:
const Button = styled.button`
background: ${props => props.$primary ? 'palevioletred' : 'white'};
color: ${props => props.$primary ? 'white' : 'palevioletred'};
`;
传个 $primary 属性,按钮就变色。$ 前缀是 transient prop,不会被传到 DOM 节点上。
还能继承:
const TomatoButton = styled(Button)`
background: tomato;
border-color: tomato;
`;
在 Button 基础上改个颜色,新的组件就出来了。

3、 该有的都有
伪类、伪元素、嵌套选择器,直接用 & 引用当前组件的类名:
const Input = styled.input`
border: 1px solid #ccc;
&:focus {
border-color: palevioletred;
outline: none;
}
&::placeholder {
color: #aaa;
}
`;
媒体查询、动画关键帧、全局样式,CSS 支持的它基本都支持。
主题系统用 ThemeProvider 包一层,所有子组件通过 props.theme 拿到设计变量:
const theme = { fg: 'palevioletred', bg: 'white' };
<ThemeProvider theme={theme}>
<Card>内容</Card>
</ThemeProvider>
还有个 createTheme 方法,把设计变量转成 CSS 自定义属性,做亮色/暗色主题切换的时候,类名哈希值保持稳定,不会出现 hydration 不匹配的问题。
4、 实际用起来怎么样
体积小,gzip 之后不到 13kB,不用装额外的构建插件。
TypeScript 类型是内置的,不用单独装 @types,props 能直接推导到样式里。
服务端渲染、React Server Components、流式 SSR、React Native,一套 API 全覆盖。运行时自动检测环境,不用手动配置。
css helper 可以把公共样式块提出来复用:
const truncate = css`
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
`;
const Label = styled.span`
${truncate}
max-width: 200px;
`;
as prop 可以在不改样式的情况下换掉渲染的 HTML 元素。attrs 可以给组件设置默认的 HTML 属性。
5、 谁在用
只要你的项目用 React,就需要管样式。styled-components 适合这些场景:
- 组件库开发,需要严格隔离样式作用域
- 需要主题切换的产品,比如暗色模式
- 用 Next.js 做 SSR 的项目,需要和 RSC 兼容
- React Native 项目,想用同一套写法管 Web 和移动端的样式
十年了,API 稳定,社区成熟,遇到问题基本都能搜到答案。
需要主题切换的产品,比如暗色模式
- 用 Next.js 做 SSR 的项目,需要和 RSC 兼容
- React Native 项目,想用同一套写法管 Web 和移动端的样式
十年了,API 稳定,社区成熟,遇到问题基本都能搜到答案。
更多推荐

所有评论(0)