CSS-in-JS vs 传统CSS:现代样式方案选择指南
在前端开发中,样式处理是一个非常重要的部分。我们经常需要给网页添加颜色、布局、动画等视觉效果,这时候就要用到样式技术。目前主流的方式主要有两种:传统CSS 和 CSS-in-JS。
这篇教程面向完全零基础的初学者,旨在通过实际案例和简单语言帮助你理解两者的区别,并能根据自己的项目需求做出合理的选择。
一、开篇:什么是 CSS-in-JS?它和传统 CSS 有什么不同?

🧱 传统 CSS(Cascading Style Sheets)
- 是最早也是最广泛使用的网页样式技术。
- 样式写在一个
.css文件里,然后通过 HTML 的<link>标签引用。 - 它的优点是简单、易学、浏览器兼容性好。
- 但缺点也逐渐显现:全局命名冲突、难以维护、缺乏模块化支持。
💡 CSS-in-JS(Styling with JavaScript)
- 把 CSS 直接写进 JavaScript 文件中。
- 通常结合 React 或 Vue 等现代前端框架使用。
- 借助 JS 的能力,可以动态生成样式、作用域隔离、避免类名冲突。
- 代表工具有
styled-components、emotion.js、JSS、CSS Modules等。
✅ 总结一句话:
传统 CSS 是“写在外部文件里的纯样式”,而 CSS-in-JS 是“写在代码中的可编程样式”。
二、环境准备:搭建你的第一个样式实验环境

无论你选择哪种方式,都需要一个基本的开发环境来练习。我们先从创建一个简单的 HTML + JS 网页开始。
1. 创建项目结构(以 VS Code 为例)
打开终端,运行以下命令创建项目文件夹:
mkdir my-style-demo
cd my-style-demo
code .
然后手动创建如下文件结构:
my-style-demo/
│
├── index.html
├── styles.css
└── app.js
2. 编写 index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>CSS 学习之旅</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div id="app"></div>
<script src="app.js" type="module"></script>
</body>
</html>
3. 启动本地服务器
推荐使用 Live Server 插件(VS Code)或运行以下命令启动简易服务器:
npx serve .
现在你可以访问 http://localhost:5000 查看页面了!
三、核心概念讲解
为了便于理解,我们将分别介绍传统 CSS 和 CSS-in-JS 的核心概念,并给出每种方式下的具体例子。
1️⃣ 传统 CSS 的工作方式
📌 特点:
- 全局作用域(容易冲突)
- 需要手动管理类名
- 样式与内容分离
✅ 示例:为按钮加样式
在 styles.css 中写入:
.my-button {
background-color: #4CAF50;
color: white;
padding: 10px 20px;
border: none;
cursor: pointer;
}
.my-button:hover {
background-color: #45a049;
}
在 app.js 中插入按钮:
const button = document.createElement('button');
button.className = 'my-button';
button.textContent = '点击我';
document.getElementById('app').appendChild(button);
🎯 效果:你会看到一个绿色按钮,鼠标悬停时颜色变深。
2️⃣ CSS-in-JS 的工作方式(以 styled-components 为例)
📌 特点:
- 局部作用域(无命名冲突)
- 支持变量、条件逻辑
- 更适合组件化的前端架构(如 React)
✅ 安装和引入(浏览器端模拟)
由于我们在原生 JS 环境下练习,我们通过 CDN 引入 styled-components。
修改 index.html 的 <head> 部分:
<script src="https://unpkg.com/@emotion/react@11.11.1/dist/emotion-react.umd.min.js"></script>
<script src="https://unpkg.com/@emotion/styled@11.11.0/dist/emotion-styled.umd.min.js"></script>
💡 我们这里使用的是 @emotion/styled,它是 styled-components 的轻量替代品,可在浏览器直接运行。
✅ 在 app.js 中定义样式组件:
const styled = window['@emotion/styled'];
const MyButton = styled.button`
background-color: #2196F3;
color: white;
padding: 10px 20px;
border: none;
cursor: pointer;
&:hover {
background-color: #1976d2;
}
`;
const button = <MyButton>我是样式化的按钮</MyButton>;
ReactDOM.createRoot(document.getElementById('app')).render(button);
⚠️ 注意:你需要同时引入 React 库才能渲染 JSX,否则报错。
在 <head> 中再加入:
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
🧪 小贴士:如果加载太慢,可以尝试换成 cdnjs.com 上的版本。
四、实战项目:制作一个“天气卡片”组件
我们将通过这个小项目来比较两种方式的具体使用差异。
🔧 功能目标:
- 显示城市名称、温度、天气状态
- 给每个元素加上合适样式
- 模拟数据绑定,实现样式随温度变化
🗂 方法1:传统 CSS 实现
1. 修改 styles.css
.weather-card {
width: 300px;
border-radius: 10px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
padding: 20px;
background-color: #f9f9f9;
}
.city {
font-size: 24px;
font-weight: bold;
}
.temp {
font-size: 18px;
color: #e53935;
}
2. 修改 app.js
// 模拟数据
const data = {
city: "北京",
temperature: 22,
condition: "晴"
};
// 构建 DOM
const card = document.createElement("div");
card.className = "weather-card";
const cityEl = document.createElement("div");
cityEl.className = "city";
cityEl.textContent = data.city;
const tempEl = document.createElement("div");
tempEl.className = "temp";
tempEl.textContent = `${data.temperature} °C`;
card.appendChild(cityEl);
card.appendChild(tempEl);
document.getElementById('app').appendChild(card);
🧩 方法2:CSS-in-JS 实现(Emotion)
修改 app.js
const styled = window['@emotion/styled'];
const React = window.React;
const ReactDOM = window.ReactDOM;
const WeatherCard = styled.div`
width: 300px;
border-radius: 10px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
padding: 20px;
background-color: #f9f9f9;
`;
const City = styled.div`
font-size: 24px;
font-weight: bold;
`;
const Temp = styled.div`
font-size: 18px;
color: ${(props) => props.color || "#e53935"};
`;
function App() {
const [data] = React.useState({
city: "上海",
temperature: 28,
condition: "多云"
});
return (
<WeatherCard>
<City>{data.city}</City>
<Temp color="#4caf50">{data.temperature} °C</Temp>
</WeatherCard>
);
}
ReactDOM.createRoot(document.getElementById('app')).render(<App />);
✅ 对比结论:CSS-in-JS 的样式可以直接响应状态变化,并且不需要担心类名重复问题。
五、常见问题解答(FAQ)
❓ Q1:我应该选传统 CSS 还是 CSS-in-JS?
| 条件 | 推荐方式 |
|---|---|
| 学习 HTML/CSS 基础 | 传统 CSS |
| 使用 React/Vue 等现代框架 | CSS-in-JS(推荐 emotion 或 styled-components) |
| 大型应用、团队协作 | CSS-in-JS / CSS Modules |
| 轻量级页面、快速部署 | 传统 CSS |
❓ Q2:为什么我的类名没生效?
- 检查 HTML 是否正确链接了 CSS 文件
- 类名拼写是否一致
- 浏览器开发者工具查看样式是否被覆盖
❓ Q3:React 中如何引入 CSS 文件?
很简单,在组件顶部:
import './MyComponent.css';
❓ Q4:CSS-in-JS 性能差吗?
- 现代库已经做了很好的优化
- 初次加载可能略慢,但热更新快
- 可以按需加载样式,提升性能
六、下一步学习建议
📘 学习路径推荐:
基础阶段
- 学习 HTML 基础语法
- 熟悉 CSS 选择器、盒模型、布局
- 了解 Flexbox、Grid 等现代布局技术
进阶阶段
- 学会使用 CSS 预处理器(如 SASS、Less)
- 开始接触模块化 CSS(CSS Modules)
- 了解 PostCSS 工作流
高阶实践
- 结合 React 或 Vue 使用 CSS-in-JS 方案
- 掌握样式系统集成工具(如 Tailwind CSS、Bootstrap)
- 掌握设计系统(Design System)理念
推荐资源
🎯 总结
本篇文章为你打开了前端样式世界的两扇门:传统 CSS 和 CSS-in-JS。你可以根据项目的复杂度和自身习惯来选择不同的方案。
- 传统 CSS 简单、直观、适合基础项目;
- CSS-in-JS 更强大、更现代,尤其适合使用 React 等组件化框架的项目。
无论你选择哪一种,关键是动手实践,不断尝试。前端世界充满可能性,希望你能找到最适合自己的风格。
🎯 下一步:试着用自己的方式改写“天气卡片”组件,看看能不能实现不同的配色切换功能吧!

评论 0