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

技术拾荒者
2025-12-12 19:13
阅读 794

大家好,我是小林,一名985毕业的全栈工程师,也是掘金上的一名技术博主。最近在带实习生时发现,很多刚接触 React 的同学对“样式怎么写”这个问题特别迷茫——到底是用传统的 .css 文件?还是用 styled-components 这类 CSS-in-JS 方案?我当初学的时候也踩过不少坑,所以今天就来写一篇零基础也能看懂的对比教程,帮你理清思路,做出适合自己的技术选型。


一、为什么会有两种样式写法?

在前端开发中,样式(CSS) 是让网页“好看”的关键。但在 React 这样的组件化框架中,传统的全局 CSS 容易造成样式冲突难以维护的问题。

于是社区提出了 CSS-in-JS 的概念:把 CSS 写在 JavaScript 里,和组件绑定在一起。这样每个组件的样式都是独立的,不会互相干扰。

✅ 简单说:

  • 传统 CSS:样式写在 .css 文件里,通过 className 引用
  • CSS-in-JS:样式直接写在 JS/JSX 里,和组件代码放一起

二、环境准备(以 Vite + React 为例)

我们用最简单的工具链来演示。打开终端,执行以下命令:

# 创建项目
npm create vite@latest my-style-demo -- --template react
cd my-style-demo

# 安装依赖
npm install

# 启动开发服务器
npm run dev

现在你有了一个干净的 React 项目。接下来我们分别实现两种样式方案。


三、核心概念对比

1. 传统 CSS 写法

这是最经典的方式:创建 .css 文件,定义类名,然后在 JSX 中通过 className 使用。

优点:简单直观,浏览器原生支持,学习成本低
缺点:类名全局污染,难以实现动态样式

示例代码

// App.jsx
import './App.css';

function App() {
  return (
    <div className="card">
      <h2>这是传统 CSS</h2>
    </div>
  );
}

export default App;
/* App.css */
.card {
  padding: 16px;
  background-color: #f0f0f0;
  border-radius: 8px;
}

2. CSS-in-JS 写法(以 styled-components 为例)

你需要先安装库:

npm install styled-components

然后直接在 JS 中定义“带样式的组件”。

优点:自动作用域隔离、支持动态传参、逻辑与样式更紧密
缺点:需要额外依赖,运行时有一定开销

示例代码

// App.jsx
import styled from 'styled-components';

const StyledCard = styled.div`
  padding: 16px;
  background-color: #f0f0f0;
  border-radius: 8px;
`;

function App() {
  return (
    <StyledCard>
      <h2>这是 CSS-in-JS</h2>
    </StyledCard>
  );
}

export default App;

四、实战:做一个带主题切换的按钮

我们来做一个小功能:点击按钮切换“亮色/暗色”主题。这能很好体现两种方案的差异。

方案一:传统 CSS 实现

// Button.jsx
import './Button.css';
import { useState } from 'react';

export default function Button() {
  const [darkMode, setDarkMode] = useState(false);

  return (
    <button
      className={`btn ${darkMode ? 'btn-dark' : 'btn-light'}`}
      onClick={() => setDarkMode(!darkMode)}
    >
      切换主题(传统 CSS)
    </button>
  );
}
/* Button.css */
.btn {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}

.btn-light {
  background-color: #ffffff;
  color: #333333;
}

.btn-dark {
  background-color: #333333;
  color: #ffffff;
}

💡 注意:这里用了两个类名组合,容易出错,且类名是全局的!


方案二:CSS-in-JS 实现(styled-components)

// Button.jsx
import styled from 'styled-components';
import { useState } from 'react';

const StyledButton = styled.button`
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  
  /* 根据 props 动态设置样式 */
  background-color: ${props => props.dark ? '#333333' : '#ffffff'};
  color: ${props => props.dark ? '#ffffff' : '#333333'};
`;

export default function Button() {
  const [darkMode, setDarkMode] = useState(false);

  return (
    <StyledButton
      dark={darkMode}
      onClick={() => setDarkMode(!darkMode)}
    >
      切换主题(CSS-in-JS)
    </StyledButton>
  );
}

✅ 优势很明显:

  • 样式和逻辑在一个文件
  • 通过 props 直接控制样式,无需管理多个类名
  • 自动避免命名冲突

五、技术选型对比表

对比维度 传统 CSS CSS-in-JS(如 styled-components)
学习成本 ⭐ 极低(HTML/CSS 基础即可) ⭐⭐ 需要理解 JS 模板字符串、props
作用域 全局(需靠命名规范避免冲突) 组件级(自动隔离)
动态样式 需切换 class,较繁琐 直接通过 props 控制,非常灵活
性能 静态文件,加载快 运行时生成 CSS,有轻微开销
工具链支持 所有编辑器原生支持 需要插件(如 VS Code 的 styled-components 插件)
调试体验 浏览器 DevTools 直接查看 生成的 class 名较乱,但可配置
适用场景 简单项目、静态页面 复杂交互、主题系统、组件库开发

六、新手常见问题解答

Q1:CSS-in-JS 会不会很慢?

:对于绝大多数应用,性能差异可以忽略。现代 CSS-in-JS 库(如 emotion)做了大量优化。只有在极端高性能场景(如动画密集的 Canvas 应用)才需要谨慎评估。

Q2:我该从哪种开始学?

:如果你是完全零基础,建议先掌握传统 CSS。因为:

  • 它是 Web 开发的基石
  • 理解盒模型、布局等概念后,再学 CSS-in-JS 更容易

等你熟悉 React 组件后,再尝试 CSS-in-JS。

Q3:能不能混用?

:完全可以!比如:

  • 页面整体布局用传统 CSS(如 layout.css
  • 可复用的 UI 组件用 CSS-in-JS

很多大厂项目都是混合使用。

Q4:有没有不依赖运行时的 CSS-in-JS?

:有!比如 LinariaVanilla Extract,它们在构建时就把 JS 转成静态 CSS,兼顾了作用域隔离和性能。不过对初学者稍复杂,建议后期再了解。


七、学习建议与避坑指南

🚶‍♂️ 学习路径推荐

  1. 先掌握基础 CSS:盒模型、Flex/Grid 布局、响应式设计
  2. 熟练使用 React 组件和 props
  3. 尝试 styled-components:从简单按钮、卡片开始
  4. 进阶学习:CSS Modules(传统 CSS 的模块化方案)、Tailwind CSS(实用优先的原子化 CSS)
  5. 探索现代方案:如 Vanilla Extract、Compiled CSS-in-JS

⚠️ 避坑提醒

  • 不要为了用新技术而用:如果项目很简单,传统 CSS 完全够用
  • 避免过度嵌套:CSS-in-JS 中不要写太深的嵌套选择器,违背组件化思想
  • 注意 SSR 支持:服务端渲染时,确保 CSS-in-JS 库正确注入样式(styled-components 默认支持)

结语

我当初学 React 时,也曾纠结“到底该用哪种样式方案”。后来明白:没有银弹,只有合适。传统 CSS 是根基,CSS-in-JS 是利器。作为初学者,先打好基础,再根据项目需求灵活选择。

希望这篇教程能帮你少走弯路。如果你觉得有用,欢迎在掘金关注我,我会持续分享更多零基础友好的前端实战内容!

技术选型的本质,不是追逐潮流,而是解决问题。
—— 你的朋友,小林

评论 0

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