初学者选样式方案,别再被CSS-in-JS绕晕了!
大家好,我是前端团队的培训负责人,带过不下50位应届生。每次新人入职,总会有人问我:“老师,现在写样式到底该用传统CSS还是CSS-in-JS啊?网上说法太乱了!”
我当初学的时候也踩过坑——为了“潮流”硬上CSS-in-JS,结果项目一复杂就维护不动;后来又听说“传统CSS过时了”,吓得差点把老项目重写。其实,没有绝对的好坏,只有适不适合。
今天这篇教程,我就用最直白的方式,带你从零搞懂这两种方案,并结合 React(目前最主流的前端框架)和一个超小实战项目(对,连爬虫都用不上那么复杂!),帮你做出适合自己的选择。
一、先搞清楚:我们到底在比什么?
1.1 传统 CSS 是什么?
就是你最早接触的那种 .css 文件:
/* styles.css */
.title {
color: blue;
font-size: 24px;
}
然后在 HTML 或 React 组件里引入:
// App.js
import './styles.css';
function App() {
return <h1 className="title">Hello World</h1>;
}
特点:
- 文件独立,结构清晰
- 浏览器原生支持,性能好
- 全局作用域(容易命名冲突!)
1.2 CSS-in-JS 又是什么?
顾名思义,把 CSS 写在 JavaScript 里。常见库有 styled-components、Emotion 等。比如用 styled-components:
// App.js
import styled from 'styled-components';
const Title = styled.h1`
color: blue;
font-size: 24px;
`;
function App() {
return <Title>Hello World</Title>;
}
特点:
- 样式和组件写在一起,逻辑内聚
- 自动解决命名冲突(每个组件样式独立)
- 支持动态样式(比如根据 props 改颜色)
- 需要额外依赖库,增加打包体积
📌 小贴士:很多人以为“CSS-in-JS = 新潮 = 更好”,其实大厂项目里两种方案并存很常见。关键是看场景!
二、动手前:搭建你的开发环境
别担心,我们用最简单的工具链。全程只需要 Node.js 和一个命令。
步骤 1:安装 Node.js
去 https://nodejs.org 下载 LTS 版(长期支持版),安装即可。
步骤 2:创建 React 项目
打开终端,运行:
npx create-react-app css-comparison-demo
cd css-comparison-demo
npm start
等几秒,浏览器会自动打开 http://localhost:3000,看到 React 默认页面就成功了!
⚠️ 注意:不要手动装 Webpack、Babel!Create React App 已经帮你配置好了,新手千万别折腾这些,容易劝退。
三、核心概念对比:一张表说清区别
| 对比项 | 传统 CSS | CSS-in-JS(以 styled-components 为例) |
|---|---|---|
| 文件位置 | 独立 .css 文件 |
写在 .js 或 .jsx 文件中 |
| 作用域 | 全局(需靠命名规范避免冲突) | 自动局部作用域(每个组件独立) |
| 动态样式 | 需配合 JS 修改 class 或 style | 直接用 props 控制,超方便 |
| 性能 | 原生,无额外开销 | 运行时生成 CSS,略慢(但通常可忽略) |
| 学习成本 | 几乎为零 | 需学新语法和库 |
| 调试 | 浏览器开发者工具直接看 | 类名是随机生成的(如 sc-bdvvaa),但 DevTools 插件可优化 |
四、实战:用两种方式写同一个卡片组件
我们要做一个简单的“用户信息卡片”,包含头像、名字和状态(在线/离线)。状态不同,边框颜色不同。
4.1 用传统 CSS 实现
步骤 1:创建 UserCard.js
// src/components/UserCard.js
import './UserCard.css';
function UserCard({ name, status }) {
return (
<div className={`user-card user-status-${status}`}>
<div className="avatar"></div>
<div className="name">{name}</div>
</div>
);
}
export default UserCard;
步骤 2:创建 UserCard.css
/* src/components/UserCard.css */
.user-card {
border: 2px solid;
border-radius: 8px;
padding: 16px;
width: 200px;
display: flex;
align-items: center;
gap: 12px;
}
.avatar {
width: 40px;
height: 40px;
background-color: #ccc;
border-radius: 50%;
}
.name {
font-size: 16px;
}
.user-status-online {
border-color: green;
}
.user-status-offline {
border-color: gray;
}
步骤 3:在 App.js 中使用
import UserCard from './components/UserCard';
function App() {
return (
<div>
<UserCard name="张三" status="online" />
<UserCard name="李四" status="offline" />
</div>
);
}
✅ 优点:结构清晰,CSS 可复用
❌ 缺点:要手动管理类名,user-status-online 这种命名容易冲突
4.2 用 CSS-in-JS(styled-components)实现
步骤 1:先安装库
npm install styled-components
步骤 2:创建 UserCardStyled.js
// src/components/UserCardStyled.js
import styled from 'styled-components';
const Card = styled.div`
border: 2px solid;
border-radius: 8px;
padding: 16px;
width: 200px;
display: flex;
align-items: center;
gap: 12px;
border-color: ${props => props.status === 'online' ? 'green' : 'gray'};
`;
const Avatar = styled.div`
width: 40px;
height: 40px;
background-color: #ccc;
border-radius: 50%;
`;
const Name = styled.div`
font-size: 16px;
`;
function UserCard({ name, status }) {
return (
<Card status={status}>
<Avatar />
<Name>{name}</Name>
</Card>
);
}
export default UserCard;
步骤 3:在 App.js 中使用(和上面一样)
import UserCard from './components/UserCardStyled'; // 改个路径就行
function App() {
return (
<div>
<UserCard name="张三" status="online" />
<UserCard name="李四" status="offline" />
</div>
);
}
✅ 优点:状态逻辑直接写在样式里,不用记一堆类名
❌ 缺点:多装了一个库,代码看起来“不像 CSS”
💡 我当初第一次看到
${props => ...}时懵了,以为是模板字符串错误。其实这是 styled-components 的“插值”语法,专门用来动态传值。
五、新手常问的5个问题
Q1:CSS-in-JS 会不会影响性能?
答:日常项目几乎没影响。只有在极端场景(比如渲染上千个动态组件)才需要考虑。React 本身开销比这个大得多。
Q2:传统 CSS 能不能做到局部作用域?
答:可以!用 CSS Modules:
// UserCard.module.css
.card { /* ... */ }
import styles from './UserCard.module.css';
<div className={styles.card}></div>
这样类名会被自动哈希化,避免冲突。很多团队用它替代 CSS-in-JS。
Q3:爬虫能看到 CSS-in-JS 生成的样式吗?
答:能!因为最终都会变成 <style> 标签插入 HTML。搜索引擎爬虫(包括 Google)都能正常解析。不用担心 SEO。
🕵️♂️ 顺便澄清:这里说的“爬虫”是指搜索引擎爬虫,不是你自己写的 Python 爬虫。如果是后者,只要页面能渲染出来,样式对数据抓取没影响。
Q4:我该学哪种?
答:
- 如果你刚学 React,先掌握传统 CSS + CSS Modules,打好基础
- 如果你做复杂交互(比如主题切换、动态皮肤),再学 CSS-in-JS
- 大厂面试常问区别,但实际工作中两种都可能用到
Q5:有没有“最好”的方案?
答:没有!甚至还有人用 Sass、Less、Tailwind CSS……
关键不是工具,而是理解“为什么需要这个方案”。比如:
- 全局样式(如 reset.css)→ 传统 CSS
- 组件私有样式 → CSS-in-JS 或 CSS Modules
- 快速原型 → Tailwind 这类原子化 CSS
六、给初学者的学习建议
- 别追求“最新”:技术圈总吹新方案,但传统 CSS 永远不会淘汰。先学会走路,再学跑。
- 动手比看文档重要:照着本文的代码敲一遍,比读十篇理论文章有用。
- 遇到报错别慌:90% 的问题都是拼写错误或忘了 import。仔细看控制台红字。
- 不要过早优化:小项目用哪种都行,等项目大了再重构也不迟。
- 关注“解决问题”:样式方案只是工具,目标是做出好用的界面。
七、下一步怎么学?
如果你已经跑通了上面的例子,可以尝试:
- 加个“主题切换”功能:用 CSS-in-JS 实现暗黑模式,体会动态样式的威力
- 试试 CSS Modules:把传统 CSS 示例改成模块化写法
- 看看 Tailwind CSS:另一种现代方案,写 class 就能出样式
- 读官方文档:
最后送大家一句话:“工具没有银弹,只有合适与否。”
我带过的新人里,最快上手的不是技术最强的,而是愿意动手、不怕犯错、懂得根据场景选择工具的人。希望你也是!
有问题欢迎留言,我会一一回复。祝你前端之路越走越顺!

评论 0