零基础如何选对前端样式方案?CSS-in-JS 还是传统 CSS?

线上稳定吗
2026-02-24 11:01
阅读 1664

大家好,我是掘金上那个总爱写“手把手”教程的全栈工程师。最近收到不少刚入门前端的朋友私信问我:“现在写样式到底该用哪种方式?网上有人说 CSS-in-JS 更现代,有人坚持传统 CSS 更稳,我该听谁的?”

说实话,我当初学的时候也踩过这个坑——花了一周时间折腾 styled-components,结果项目上线才发现性能有点吃紧;后来又回头啃原生 CSS 模块化,走了不少弯路。所以今天,我就用自己的实战经验,带大家从零搞懂 CSS-in-JS 和传统 CSS 的区别、适用场景和选择建议。


一、它们到底是什么?

传统 CSS:老朋友,但不简单

传统 CSS 就是我们最熟悉的 .css 文件 + class 的写法:

<!-- index.html -->
<div class="header">欢迎来到我的网站</div>
/* styles.css */
.header {
  background: #42b883;
  padding: 16px;
  color: white;
}

这种写法简单直观,浏览器天生支持,无需额外工具。但随着项目变大,容易出现 类名冲突、全局污染、难以维护 的问题。

CSS-in-JS:把 CSS 写进 JavaScript 里

CSS-in-JS 是一种思想:用 JS 对象或模板字符串来定义样式,并动态注入到页面中。常见库有 styled-components、Emotion 等。

例如用 styled-components:

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

const StyledHeader = styled.div`
  background: #42b883;
  padding: 16px;
  color: white;
`;

export default function Header() {
  return <StyledHeader>欢迎来到我的网站</StyledHeader>;
}

它的核心优势是:作用域隔离(自动防冲突)、动态样式(基于 props)、组件即样式


二、环境准备:5 分钟搭起实验场

我们用最简单的 Vite + React 来搭建两个对比项目。

步骤 1:安装 Node.js

确保你已安装 Node.js(建议 18+ 版本)。

步骤 2:创建传统 CSS 项目

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

然后在 src/App.jsx 中引入 CSS:

import './App.css';

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

export default App;

src/App.css 中写样式:

.card {
  padding: 12px;
  border: 1px solid #ccc;
  margin: 10px;
}

步骤 3:创建 CSS-in-JS 项目

npm create vite@latest js-css-demo -- --template react
cd js-css-demo
npm install styled-components
npm run dev

修改 src/App.jsx

import styled from 'styled-components';

const Card = styled.div`
  padding: 12px;
  border: 1px solid #ccc;
  margin: 10px;
`;

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

export default App;

✅ 到这里,你就有了两个可运行的对比环境!


三、核心概念对比:新手必须知道的 4 点

维度 传统 CSS CSS-in-JS
作用域 全局(需靠命名规范避免冲突) 自动局部作用域(每个组件独立)
动态样式 需配合 JS 切换 class 或内联 style 直接通过 props 控制样式
性能 浏览器原生优化,首屏快 运行时生成样式,有一定开销
调试体验 DevTools 直接看到 class 名 类名是哈希值(如 .sc-fjdjdk),需插件辅助

动态样式的实战对比

假设我们要根据 type 属性改变按钮颜色:

传统 CSS 方案

function Button({ type, children }) {
  const baseClass = 'btn';
  const typeClass = type === 'primary' ? 'btn-primary' : 'btn-secondary';
  return <button className={`${baseClass} ${typeClass}`}>{children}</button>;
}
.btn { padding: 8px 16px; }
.btn-primary { background: blue; color: white; }
.btn-secondary { background: gray; color: black; }

CSS-in-JS 方案

const Button = styled.button`
  padding: 8px 16px;
  background: ${props => props.type === 'primary' ? 'blue' : 'gray'};
  color: ${props => props.type === 'primary' ? 'white' : 'black'};
`;

// 使用
<Button type="primary">主要按钮</Button>

👉 明显后者更简洁,逻辑集中在一个地方。


四、动手做个对比小项目

我们来做一个“主题切换器”,体验两种方案的差异。

传统 CSS 实现

  1. 定义两个主题的 CSS:
/* light-theme.css */
.theme-light { --bg: white; --text: black; }

/* dark-theme.css */
.theme-dark { --bg: #121212; --text: white; }

/* 公共样式 */
.app {
  background: var(--bg);
  color: var(--text);
  transition: background 0.3s;
}
  1. 在 JS 中切换 class:
function App() {
  const [theme, setTheme] = useState('light');
  
  useEffect(() => {
    document.body.className = `theme-${theme}`;
  }, [theme]);

  return (
    <div className="app">
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        切换主题
      </button>
    </div>
  );
}

CSS-in-JS 实现

const AppContainer = styled.div`
  background: ${props => props.theme.bg};
  color: ${props => props.theme.text};
  transition: background 0.3s;
  padding: 20px;
`;

const themes = {
  light: { bg: 'white', text: 'black' },
  dark: { bg: '#121212', text: 'white' }
};

function App() {
  const [current, setCurrent] = useState('light');
  
  return (
    <AppContainer theme={themes[current]}>
      <button onClick={() => setCurrent(current === 'light' ? 'dark' : 'light')}>
        切换主题
      </button>
    </AppContainer>
  );
}

💡 关键区别:传统方案依赖 DOM 操作和 CSS 变量,CSS-in-JS 把主题数据直接传给组件,更符合 React 的数据流思想。


五、新手常问的 3 个问题

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

会,但要看场景。

  • 小型项目/内部系统:几乎无感。
  • 高流量、SEO 敏感的页面:传统 CSS + 静态文件缓存更优。
  • 解决方案:Emotion 支持 SSR 提取静态 CSS,可兼顾动态性和性能。

Q2:团队该统一用哪种?

建议:

  • 如果团队熟悉 BEM 命名、有良好 CSS 规范 → 传统 CSS + CSS Modules 足够。
  • 如果重度使用 React/Vue,追求组件自治 → CSS-in-JS 更爽。
  • 混合使用也是常态:全局样式用传统 CSS,组件样式用 CSS-in-JS。

Q3:GitHub 上哪些项目值得参考?

  • 传统 CSS 范例Ant Design —— 使用 LESS + BEM。
  • CSS-in-JS 范例Material UI —— 早期用 JSS,现转向 emotion。
  • 新手可 clone 这些项目,看他们如何组织样式代码。

六、AI 工具能帮我们什么?

如今写样式,很多人会借助 AI 辅助。我试过几个主流工具:

工具 对 CSS 的支持 实测体验
文心一言 能生成基础 CSS,但对 CSS-in-JS 不熟 适合初学者查语法
ChatGPT 熟悉 styled-components、emotion,能写完整组件 推荐!可让它对比两种写法
Claude Code 支持上下文理解,能根据现有代码风格续写 适合已有项目扩展示例

举个例子,你可以这样问 ChatGPT:

“用 styled-components 写一个响应式卡片,手机端宽度 100%,桌面端 300px”

它会直接给你可用代码,省去查文档的时间。

⚠️ 但注意:AI 不能替代你理解原理。我见过新手直接复制 AI 代码,结果线上样式错乱,因为没理解媒体查询或盒模型。


七、学习建议与避坑指南

我的建议路径:

  1. 先掌握传统 CSS 基础(盒模型、定位、Flex/Grid)—— 这是地基。
  2. 学 CSS Modules:解决全局污染问题,过渡自然。
  3. 再尝试 CSS-in-JS:理解其设计哲学,而非盲目跟风。
  4. 最终目标:能根据项目需求灵活选择,甚至混合使用。

避坑提醒:

  • ❌ 不要一上来就学 Tailwind CSS + CSS-in-JS 混用(太混乱)。
  • ✅ 小项目练手优先用传统 CSS,感受“痛点”后再引入新方案。
  • 🔍 学会用浏览器 DevTools 查看生成的样式,理解底层机制。

结语

没有“最好”的方案,只有“更适合”的选择。我在 GitHub 上开源的个人博客用的是传统 CSS + PostCSS,而公司后台系统则全面拥抱 styled-components。关键在于理解每种方案的 trade-off(权衡)

希望这篇教程能帮你少走弯路。如果你觉得有用,欢迎去我的掘金主页点赞关注——那里还有更多“从踩坑到填坑”的实战分享!

下次见!

评论 0

最热最新
暂无评论
线上稳定吗Lv.1
0
影响力
0
文章
0
粉丝