CSS-in-JS vs 传统CSS:现代样式方案选择指南
大家好,我是小林,一名在大厂干了3年前端开发的工程师,业余时间也在B站做技术UP主。最近在评论区和私信里,收到不少零基础同学的问题:“现在写样式到底该用传统的 CSS 文件,还是用 CSS-in-JS?”、“简历上写哪种技术更有竞争力?”、“这两种方式有什么区别?”
我当初学前端的时候也踩过类似的坑——一开始只会 <style> 标签内写样式,后来学了 .css 文件,再后来接触 React 项目,突然冒出一堆 styled-components、emotion 这些陌生名词,完全懵了。
所以今天这篇技术分享,就是专门为完全零基础的同学写的。我会用最直白的语言,带你从“什么是样式”开始,一步步理解 CSS-in-JS 和传统 CSS 的区别,并通过一个实战项目让你亲手体验两者的差异。最后还会告诉你:在简历上该怎么写、怎么选,才不被面试官问住!
一、为什么会有两种写样式的方式?
1.1 传统 CSS:网页的“衣服设计师”
想象一下,你有一个 HTML 元素(比如一个按钮),你想给它穿一件红色的衣服、加个圆角。在传统方式中,你会:
- 写一个
.button { color: red; border-radius: 8px; }的规则 - 在 HTML 中给按钮加上
class="button"
这就是 传统 CSS —— 样式和结构分离,像设计师和裁缝分工合作。
✅ 优点:
- 简单直观,浏览器原生支持
- 学习成本低,适合静态页面
- 性能好(直接由浏览器解析)
❌ 缺点:
- 全局作用域:
.button可能在其他地方被意外覆盖 - 难以动态化:比如“根据用户主题切换颜色”需要 JavaScript 手动操作 class
- 组件复用困难:React/Vue 组件希望“样式跟着组件走”,但 CSS 是全局的
1.2 CSS-in-JS:把样式“塞进”JavaScript 里
为了解决上述问题,社区发明了 CSS-in-JS —— 直接在 JS 代码里写样式。
比如用 styled-components(一个流行的 CSS-in-JS 库):
import styled from 'styled-components';
const RedButton = styled.button`
color: red;
border-radius: 8px;
`;
你看,样式直接写在 JS 变量里!这个 RedButton 就是一个自带样式的 React 组件。
✅ 优点:
- 自动作用域隔离(每个组件样式独立)
- 支持动态样式(比如
props => color: ${props.theme}) - 更符合组件化思想
❌ 缺点:
- 需要额外依赖(增加包体积)
- 学习曲线稍陡(要理解模板字符串、props 等)
- 调试不如传统 CSS 直观(开发者工具里类名是随机的)
📌 一句话总结:
传统 CSS = 外部文件管理样式
CSS-in-JS = 在 JS 里直接定义样式
二、环境准备:搭建你的第一个项目
我们来分别创建两个小项目,体验两种方式。
2.1 准备工作
你需要安装:
- Node.js(推荐 v18+)
- 一个代码编辑器(如 VS Code)
打开终端,执行:
# 创建项目文件夹
mkdir css-comparison
cd css-comparison
# 初始化 npm 项目
npm init -y
2.2 传统 CSS 项目
# 创建传统 CSS 项目
mkdir traditional-css
cd traditional-css
# 创建 index.html 和 style.css
echo '<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<button class="my-button">传统按钮</button>
</body>
</html>' > index.html
echo '.my-button {
background: blue;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
}' > style.css
双击 index.html 用浏览器打开,就能看到蓝色按钮!
2.3 CSS-in-JS 项目(使用 Vite + React)
CSS-in-JS 主要在 React 等框架中使用。我们用 Vite 快速搭建:
# 回到根目录
cd ..
# 使用 Vite 创建 React 项目
npm create vite@latest css-in-js-demo -- --template react
cd css-in-js-demo
npm install
# 安装 styled-components
npm install styled-components
# 启动开发服务器
npm run dev
Vite 会输出一个本地地址(如 http://localhost:5173),打开即可看到默认页面。
三、核心概念对比(附代码示例)
3.1 如何定义样式?
| 方式 | 代码示例 | 特点 |
|---|---|---|
| 传统 CSS | css<br>.btn {<br> color: red;<br>} |
全局作用域,需手动管理命名 |
| CSS-in-JS | js<br>const Btn = styled.button`<br> color: red;<br>`; |
自动局部作用域,样式绑定到组件 |
3.2 如何传递动态样式?
假设我们要做一个“根据 props 改变颜色”的按钮。
传统 CSS 做法(麻烦!):
<!-- HTML -->
<button class="btn btn-red">红按钮</button>
<button class="btn btn-blue">蓝按钮</button>
/* CSS */
.btn-red { background: red; }
.btn-blue { background: blue; }
→ 需要预先定义所有可能的 class,不灵活!
CSS-in-JS 做法(优雅!):
const DynamicButton = styled.button`
background: ${props => props.color};
color: white;
`;
// 使用
<DynamicButton color="red">红按钮</DynamicButton>
<DynamicButton color="blue">蓝按钮</DynamicButton>
→ 样式直接接收 props,动态生成!
3.3 如何处理嵌套和伪类?
传统 CSS:
.card {
padding: 16px;
}
.card:hover {
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.card .title {
font-size: 18px;
}
CSS-in-JS(以 styled-components 为例):
const Card = styled.div`
padding: 16px;
&:hover {
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.title {
font-size: 18px;
}
`;
注意:虽然可以写
.title,但更推荐用另一个 styled 组件,避免回到 class 依赖的老路。
四、实战项目:做一个主题切换按钮
我们现在用两种方式各做一个“点击切换亮/暗主题”的按钮。
4.1 传统 CSS 实现
思路:
- 定义两个 class:
.light-theme,.dark-theme - 用 JS 切换 body 的 class
- 通过 CSS 后代选择器应用不同样式
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="theme.css">
</head>
<body class="light-theme">
<button id="toggleBtn">切换主题</button>
<script src="app.js"></script>
</body>
</html>
/* theme.css */
.light-theme {
background: white;
color: black;
}
.dark-theme {
background: #121212;
color: white;
}
.light-theme button {
background: #e0e0e0;
}
.dark-theme button {
background: #424242;
color: white;
}
// app.js
let isDark = false;
document.getElementById('toggleBtn').addEventListener('click', () => {
const body = document.body;
if (isDark) {
body.className = 'light-theme';
} else {
body.className = 'dark-theme';
}
isDark = !isDark;
});
✅ 能用,但:
- 样式分散在 CSS 和 JS 中
- 主题逻辑和 UI 强耦合
- 如果有多个组件,每个都要写
.light-theme .xxx
4.2 CSS-in-JS 实现(React + styled-components)
思路:
- 用 React 的
useState管理主题状态 - 将主题通过
ThemeProvider全局传递 - styled 组件直接读取主题变量
// main.jsx
import React, { useState } from 'react';
import { createRoot } from 'react-dom/client';
import { ThemeProvider } from 'styled-components';
const lightTheme = { bg: 'white', text: 'black', btnBg: '#e0e0e0' };
const darkTheme = { bg: '#121212', text: 'white', btnBg: '#424242' };
function App() {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
setTheme(prev => prev === 'light' ? 'dark' : 'light');
};
return (
<ThemeProvider theme={theme === 'light' ? lightTheme : darkTheme}>
<div style={{ padding: '20px' }}>
<ToggleThemeButton onClick={toggleTheme} />
</div>
</ThemeProvider>
);
}
// 定义带样式的按钮
import styled from 'styled-components';
const ToggleThemeButton = styled.button`
background: ${props => props.theme.btnBg};
color: ${props => props.theme.text};
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
`;
createRoot(document.getElementById('root')).render(<App />);
✅ 优势明显:
- 样式和逻辑都在 JS 中,高内聚
- 主题变量集中管理
- 每个组件自动适配主题,无需重复写选择器
五、新手常见问题解答(FAQ)
Q1:CSS-in-JS 会不会很慢?
答:早期确实有性能问题,但现在主流库(如 emotion、styled-components)都做了优化:
- 样式只生成一次
- 自动去重
- 支持服务端渲染(SSR)
除非是超大型应用,否则性能差异几乎感知不到。
Q2:简历上该写哪种技术?
答:看岗位要求!
- 如果面传统企业站、CMS 系统 → 强调你精通 Sass、PostCSS、BEM 命名规范
- 如果面React 技术栈的大厂 → 写上 “熟悉 styled-components / emotion,实现主题系统与动态样式”
💡 避坑建议:不要写“我会 CSS-in-JS”,而要写“使用 styled-components 实现了可复用的主题切换组件,提升团队开发效率” —— 结果导向才加分!
Q3:能不能混用两种方式?
答:可以,但不推荐!
- 混用会导致样式来源混乱
- 调试困难(某个元素为啥是这个颜色?查半天发现是全局 CSS 覆盖了)
建议:一个项目统一一种方案。
Q4:CSS Modules 算哪边?
答:CSS Modules 是传统 CSS 的“升级版”,它通过编译时生成唯一 class 名实现局部作用域,属于“传统阵营的现代化方案”。如果你不想引入 JS 样式库,又想要作用域隔离,它是很好的折中选择。
六、学习建议 & 下一步路线
6.1 零基础学习路径
先掌握传统 CSS
- 学盒模型、Flex、Grid
- 掌握 BEM 命名规范
- 了解 Sass/Less 预处理器
再学组件化框架(React/Vue)
- 理解组件、props、state
最后接触 CSS-in-JS
- 从
styled-components或emotion入手 - 尝试实现动态主题、响应式样式
- 从
6.2 避坑指南(我踩过的雷)
- ❌ 不要一上来就学 CSS-in-JS!基础 CSS 不牢,你会连“为什么需要 CSS-in-JS”都不懂。
- ❌ 不要为了用新技术而用!如果项目是静态页,传统 CSS 更合适。
- ✅ 在个人项目中尝试 CSS-in-JS,把它写进简历的“项目经验”里,比单纯写“了解”有力得多。
6.3 推荐学习资源
- MDN Web Docs(免费,权威)
- 《CSS 权威指南》(书籍)
- 我的 B 站频道【小林前端课】(搜索“CSS-in-JS 实战”)
- styled-components 官方文档(英文,但示例丰富)
结语
CSS-in-JS 和传统 CSS 不是对立关系,而是不同场景下的工具选择。就像你会用螺丝刀也会用锤子,关键看钉子是什么类型。
作为前端开发者,理解问题本质比追逐新潮更重要。当你能说出“我们项目用传统 CSS + CSS Modules,因为团队习惯且性能优先”,或者“我们用 emotion 实现了设计系统的 token 化管理”,面试官就知道:你是个有思考的工程师。
最后,别忘了:技术分享的价值在于帮助他人少走弯路。如果你觉得这篇文章对你有帮助,欢迎点赞、转发,也欢迎来我 B 站评论区交流!
祝你 coding happy,offer 拿到手软!🎉

评论 0