CSS Modules 与 CSS-in-JS
两种 CSS 作用域方案的对比与使用
问题
CSS Modules 和 CSS-in-JS 分别是什么?它们如何解决样式冲突问题?
解答
CSS Modules
CSS Modules 是一种 CSS 文件的模块化方案,通过构建工具将类名转换为唯一标识符,实现样式隔离。
/* Button.module.css */
.button {
padding: 8px 16px;
border-radius: 4px;
}
.primary {
background: #1890ff;
color: white;
}
// Button.jsx
import styles from './Button.module.css';
function Button({ children, primary }) {
return (
<button className={`${styles.button} ${primary ? styles.primary : ''}`}>
{children}
</button>
);
}
// 编译后的类名类似:Button_button_x7d2s Button_primary_k3j1f
CSS-in-JS
CSS-in-JS 是在 JavaScript 中编写样式的方案,常见库有 styled-components、Emotion 等。
// 使用 styled-components
import styled from 'styled-components';
// 创建带样式的组件
const Button = styled.button`
padding: 8px 16px;
border-radius: 4px;
background: ${props => props.primary ? '#1890ff' : '#fff'};
color: ${props => props.primary ? '#fff' : '#333'};
&:hover {
opacity: 0.8;
}
`;
// 使用
function App() {
return (
<div>
<Button>默认按钮</Button>
<Button primary>主要按钮</Button>
</div>
);
}
// 使用 Emotion
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
const buttonStyle = css`
padding: 8px 16px;
border-radius: 4px;
`;
const primaryStyle = css`
background: #1890ff;
color: white;
`;
function Button({ children, primary }) {
return (
<button css={[buttonStyle, primary && primaryStyle]}>
{children}
</button>
);
}
对比
| 特性 | CSS Modules | CSS-in-JS |
|---|---|---|
| 样式位置 | 独立 CSS 文件 | JS 文件中 |
| 动态样式 | 需要条件类名 | 原生支持 props |
| 运行时开销 | 无 | 有(解析和注入) |
| 服务端渲染 | 简单 | 需要额外配置 |
| 学习成本 | 低 | 中等 |
| 类型支持 | 需要额外配置 | 天然支持 |
实际选择建议
// CSS Modules 适合:静态样式为主的项目
// styles.module.css
.card {
border: 1px solid #eee;
}
.card.active {
border-color: #1890ff;
}
// CSS-in-JS 适合:需要大量动态样式的场景
const Card = styled.div`
border: 1px solid ${props => props.active ? '#1890ff' : '#eee'};
transform: scale(${props => props.active ? 1.02 : 1});
transition: all 0.2s;
`;
关键点
- CSS Modules 通过编译时转换类名实现隔离,零运行时开销
- CSS-in-JS 在运行时生成样式,支持基于 props 的动态样式
- CSS Modules 保持 CSS 和 JS 分离,更接近传统开发方式
- CSS-in-JS 样式与组件共存,删除组件时样式自动移除
- 性能敏感场景优先 CSS Modules,交互复杂场景可选 CSS-in-JS
目录