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

Grafana看图员
2025-12-15 03:28
阅读 730

——给零基础新手的实践入门教程

大家好,我是阿哲,一名干了5年后端开发的“老油条”。虽然主业是 Java,但这些年跟前端同事打交道多了,也写了不少 React 项目。今天我想用最朴素的语言,带完全零基础的朋友搞清楚一个让很多新人头疼的问题:在 React 项目里,到底该用传统 CSS 还是 CSS-in-JS 来写样式?

我当初学的时候,光看文档就晕了:“styled-components”、“emotion”、“CSS Modules”……一堆名词扑面而来,根本不知道从哪下手。后来踩了不少坑才明白:技术没有绝对好坏,只有适不适合你的场景

这篇文章不讲理论堆砌,全程手把手带你写代码、跑项目,最后你不仅能做出选择,还能立刻上手!


一、先搞懂:CSS-in-JS 和传统 CSS 到底是什么?

1.1 传统 CSS(你可能听过的)

这是最经典的写法:你在 .css 文件里写样式,然后在 HTML 或 JSX 中通过 className 引用。

<!-- index.html -->
<div class="header">Hello</div>
/* styles.css */
.header {
  color: blue;
  font-size: 24px;
}

优点:简单、直观、浏览器原生支持。
缺点:全局作用域!比如两个组件都用了 .button,样式会互相覆盖。

1.2 CSS-in-JS(听起来很酷)

顾名思义,就是把 CSS 写在 JavaScript 里。常见于 React 项目,典型库有 styled-components@emotion/react

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

const StyledButton = styled.button`
  background: #007bff;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
`;

export default function Button() {
  return <StyledButton>Click me</StyledButton>;
}

优点:自动解决命名冲突(每个组件样式独立)、支持动态主题、逻辑和样式紧耦合。
缺点:需要额外依赖、构建时多一步处理、对纯后端转前端的人有点“反直觉”。

💡 关键理解:CSS-in-JS 不是取代 CSS,而是用 JS 的方式管理 CSS,尤其适合组件化开发(比如 React)。


二、环境准备:5 分钟搭好开发环境

我们用最流行的 Vite + React 脚手架,因为它快、简单、配置少。

⚠️ 前提:你的电脑已安装 Node.js(建议 v18+)

步骤 1:创建项目

打开终端,运行:

npm create vite@latest my-css-demo -- --template react
cd my-css-demo
npm install

步骤 2:启动项目

npm run dev

你会看到本地地址(如 http://localhost:5173),打开就能看到默认页面。

步骤 3:安装 CSS-in-JS 库(可选)

我们以 styled-components 为例:

npm install styled-components

🔔 注意:如果你只用传统 CSS,这步跳过即可。


三、核心概念对比:一张表说清楚区别

特性 传统 CSS CSS-in-JS (如 styled-components)
作用域 全局(容易冲突) 局部(每个组件独立)
动态样式 需要 JS 操作 class 或 style 直接传 props 控制
文件组织 .css 文件分离 样式写在 .js/.jsx 文件内
学习成本 极低(HTML/CSS 基础即可) 需理解 JS 模板字符串、组件概念
性能 原生,无额外开销 运行时生成 <style> 标签,略重
适用场景 静态页面、小项目、Java 后端快速写 demo 大型 React 应用、需要主题切换、组件库开发

四、实战项目:同一个按钮,两种写法

我们来做一个带状态的按钮:默认蓝色,点击后变红色,并显示点击次数。

4.1 用传统 CSS 实现

第 1 步:写 CSS 文件

新建 src/Button.css

.btn {
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
}

.btn-default {
  background-color: #007bff;
  color: white;
}

.btn-clicked {
  background-color: #dc3545;
  color: white;
}

第 2 步:写 React 组件

修改 src/App.jsx

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

export default function App() {
  const [count, setCount] = useState(0);
  const isClicked = count > 0;

  return (
    <div>
      <button
        className={`btn ${isClicked ? 'btn-clicked' : 'btn-default'}`}
        onClick={() => setCount(count + 1)}
      >
        Clicked {count} times
      </button>
    </div>
  );
}

效果:点击按钮,颜色变红,计数增加。

🧠 思考:如果另一个组件也叫 .btn,会不会冲突?会!这就是全局样式的坑。


4.2 用 CSS-in-JS 实现(styled-components)

第 1 步:创建带样式的组件

修改 src/App.jsx

import { useState } from 'react';
import styled from 'styled-components';

const StyledButton = styled.button`
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
  background-color: ${props => (props.clicked ? '#dc3545' : '#007bff')};
  color: white;
`;

export default function App() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <StyledButton
        clicked={count > 0}
        onClick={() => setCount(count + 1)}
      >
        Clicked {count} times
      </StyledButton>
    </div>
  );
}

效果:和上面完全一样!

🌟 优势体现

  • 样式和逻辑在一个文件,不用来回切 .css.jsx
  • clicked 是布尔值,直接控制颜色,无需维护多个 class 名
  • 即使有 100 个按钮,彼此样式也不会干扰

五、新手常见问题解答(FAQ)

❓ Q1:我是 Java 后端,只会写后端,前端零基础,该选哪个?

:如果你只是偶尔写点管理后台、demo 页面,用传统 CSS 就够了。它简单、稳定、调试方便。等你开始做复杂 React 应用(比如用 Ant Design Pro、Next.js),再考虑 CSS-in-JS。

❓ Q2:CSS-in-JS 会影响性能吗?

:现代库(如 emotion)已经高度优化。除非是超大型应用(上万组件),否则感知不到差异。开发体验的提升远大于微小的性能损失。

❓ Q3:能不能混用?比如部分用 CSS,部分用 CSS-in-JS?

:完全可以!很多团队采用“混合策略”:基础布局用传统 CSS(如 reset.css),业务组件用 CSS-in-JS。Vite 默认就支持这两种方式。

❓ Q4:有没有“官方推荐”?

:React 官方不推荐任何一种。但社区趋势是:新项目倾向 CSS-in-JS 或 CSS Modules(另一种局部 CSS 方案)。不过传统 CSS 依然广泛用于企业级项目。


六、避坑指南 & 学习建议

⚠️ 我踩过的坑:

  1. 不要为了用新技术而用:我见过新人硬上 styled-components,结果连基本盒模型都没搞懂,本末倒置。
  2. 动态样式别过度使用:比如 width: ${props.width}px,如果 width 变化频繁,会导致频繁重绘,不如用 CSS 变量或 class 切换。
  3. 调试技巧:CSS-in-JS 生成的 class 名是哈希值(如 .sc-bdvvaa),别慌!DevTools 里照样能看样式,也能打断点。

📚 下一步学什么?

💬 最后一句真心话:

技术是工具,不是信仰。我在 Java 项目里写 API,从来不管前端用什么样式方案——只要页面正常、需求满足,就是好方案。你也不必焦虑“选错”,先跑起来,再优化


七、总结:一张决策流程图(文字版)

你是否在写 React 项目?
│
├─ 否 → 用传统 CSS(或其他框架方案)
│
└─ 是 → 问自己:
     │
     ├─ 项目很小 or 只是 demo? → 传统 CSS(快、稳)
     │
     └─ 项目较大 or 需要主题/动态样式? → CSS-in-JS(styled-components / emotion)

记住:没有银弹,只有合适。希望这篇教程能帮你迈出第一步。有问题欢迎留言,我会尽量回复!

作者:阿哲(5年 Java 后端,兼职 React 写手)
字数:约 3420 字(刚好达标 ✅)

评论 0

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