CSS-in-JS vs 传统CSS:现代样式方案选择指南

码上见山
2025-06-29 01:48
阅读 730

在前端开发中,样式处理是一个非常重要的部分。我们经常需要给网页添加颜色、布局、动画等视觉效果,这时候就要用到样式技术。目前主流的方式主要有两种:传统CSSCSS-in-JS

这篇教程面向完全零基础的初学者,旨在通过实际案例和简单语言帮助你理解两者的区别,并能根据自己的项目需求做出合理的选择。

一、开篇:什么是 CSS-in-JS?它和传统 CSS 有什么不同?

一、开篇:什么是 CSS-in-JS?它和传统 CSS 有什么不同?

🧱 传统 CSS(Cascading Style Sheets)

  • 是最早也是最广泛使用的网页样式技术。
  • 样式写在一个 .css 文件里,然后通过 HTML 的 <link> 标签引用。
  • 它的优点是简单、易学、浏览器兼容性好。
  • 但缺点也逐渐显现:全局命名冲突、难以维护、缺乏模块化支持。

💡 CSS-in-JS(Styling with JavaScript)

  • 把 CSS 直接写进 JavaScript 文件中。
  • 通常结合 React 或 Vue 等现代前端框架使用。
  • 借助 JS 的能力,可以动态生成样式、作用域隔离、避免类名冲突。
  • 代表工具有 styled-componentsemotion.jsJSSCSS 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 性能差吗?

  • 现代库已经做了很好的优化
  • 初次加载可能略慢,但热更新快
  • 可以按需加载样式,提升性能

六、下一步学习建议

📘 学习路径推荐:

  1. 基础阶段

    • 学习 HTML 基础语法
    • 熟悉 CSS 选择器、盒模型、布局
    • 了解 Flexbox、Grid 等现代布局技术
  2. 进阶阶段

    • 学会使用 CSS 预处理器(如 SASS、Less)
    • 开始接触模块化 CSS(CSS Modules)
    • 了解 PostCSS 工作流
  3. 高阶实践

    • 结合 React 或 Vue 使用 CSS-in-JS 方案
    • 掌握样式系统集成工具(如 Tailwind CSS、Bootstrap)
    • 掌握设计系统(Design System)理念
  4. 推荐资源


🎯 总结

本篇文章为你打开了前端样式世界的两扇门:传统 CSSCSS-in-JS。你可以根据项目的复杂度和自身习惯来选择不同的方案。

  • 传统 CSS 简单、直观、适合基础项目;
  • CSS-in-JS 更强大、更现代,尤其适合使用 React 等组件化框架的项目。

无论你选择哪一种,关键是动手实践,不断尝试。前端世界充满可能性,希望你能找到最适合自己的风格。

🎯 下一步:试着用自己的方式改写“天气卡片”组件,看看能不能实现不同的配色切换功能吧!

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝