初学者选样式方案,别再被CSS-in-JS绕晕了!

网络唐志强爱好者
2026-01-14 04:10
阅读 1300

大家好,我是前端团队的培训负责人,带过不下50位应届生。每次新人入职,总会有人问我:“老师,现在写样式到底该用传统CSS还是CSS-in-JS啊?网上说法太乱了!”

我当初学的时候也踩过坑——为了“潮流”硬上CSS-in-JS,结果项目一复杂就维护不动;后来又听说“传统CSS过时了”,吓得差点把老项目重写。其实,没有绝对的好坏,只有适不适合

今天这篇教程,我就用最直白的方式,带你从零搞懂这两种方案,并结合 React(目前最主流的前端框架)和一个超小实战项目(对,连爬虫都用不上那么复杂!),帮你做出适合自己的选择。


一、先搞清楚:我们到底在比什么?

1.1 传统 CSS 是什么?

就是你最早接触的那种 .css 文件:

/* styles.css */
.title {
  color: blue;
  font-size: 24px;
}

然后在 HTML 或 React 组件里引入:

// App.js
import './styles.css';

function App() {
  return <h1 className="title">Hello World</h1>;
}

特点

  • 文件独立,结构清晰
  • 浏览器原生支持,性能好
  • 全局作用域(容易命名冲突!)

1.2 CSS-in-JS 又是什么?

顾名思义,把 CSS 写在 JavaScript 里。常见库有 styled-components、Emotion 等。比如用 styled-components

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

const Title = styled.h1`
  color: blue;
  font-size: 24px;
`;

function App() {
  return <Title>Hello World</Title>;
}

特点

  • 样式和组件写在一起,逻辑内聚
  • 自动解决命名冲突(每个组件样式独立)
  • 支持动态样式(比如根据 props 改颜色)
  • 需要额外依赖库,增加打包体积

📌 小贴士:很多人以为“CSS-in-JS = 新潮 = 更好”,其实大厂项目里两种方案并存很常见。关键是看场景!


二、动手前:搭建你的开发环境

别担心,我们用最简单的工具链。全程只需要 Node.js 和一个命令。

步骤 1:安装 Node.js

https://nodejs.org 下载 LTS 版(长期支持版),安装即可。

步骤 2:创建 React 项目

打开终端,运行:

npx create-react-app css-comparison-demo
cd css-comparison-demo
npm start

等几秒,浏览器会自动打开 http://localhost:3000,看到 React 默认页面就成功了!

⚠️ 注意:不要手动装 Webpack、Babel!Create React App 已经帮你配置好了,新手千万别折腾这些,容易劝退。


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

对比项 传统 CSS CSS-in-JS(以 styled-components 为例)
文件位置 独立 .css 文件 写在 .js.jsx 文件中
作用域 全局(需靠命名规范避免冲突) 自动局部作用域(每个组件独立)
动态样式 需配合 JS 修改 class 或 style 直接用 props 控制,超方便
性能 原生,无额外开销 运行时生成 CSS,略慢(但通常可忽略)
学习成本 几乎为零 需学新语法和库
调试 浏览器开发者工具直接看 类名是随机生成的(如 sc-bdvvaa),但 DevTools 插件可优化

四、实战:用两种方式写同一个卡片组件

我们要做一个简单的“用户信息卡片”,包含头像、名字和状态(在线/离线)。状态不同,边框颜色不同。

4.1 用传统 CSS 实现

步骤 1:创建 UserCard.js

// src/components/UserCard.js
import './UserCard.css';

function UserCard({ name, status }) {
  return (
    <div className={`user-card user-status-${status}`}>
      <div className="avatar"></div>
      <div className="name">{name}</div>
    </div>
  );
}

export default UserCard;

步骤 2:创建 UserCard.css

/* src/components/UserCard.css */
.user-card {
  border: 2px solid;
  border-radius: 8px;
  padding: 16px;
  width: 200px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.avatar {
  width: 40px;
  height: 40px;
  background-color: #ccc;
  border-radius: 50%;
}

.name {
  font-size: 16px;
}

.user-status-online {
  border-color: green;
}

.user-status-offline {
  border-color: gray;
}

步骤 3:在 App.js 中使用

import UserCard from './components/UserCard';

function App() {
  return (
    <div>
      <UserCard name="张三" status="online" />
      <UserCard name="李四" status="offline" />
    </div>
  );
}

✅ 优点:结构清晰,CSS 可复用
❌ 缺点:要手动管理类名,user-status-online 这种命名容易冲突


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

步骤 1:先安装库

npm install styled-components

步骤 2:创建 UserCardStyled.js

// src/components/UserCardStyled.js
import styled from 'styled-components';

const Card = styled.div`
  border: 2px solid;
  border-radius: 8px;
  padding: 16px;
  width: 200px;
  display: flex;
  align-items: center;
  gap: 12px;
  border-color: ${props => props.status === 'online' ? 'green' : 'gray'};
`;

const Avatar = styled.div`
  width: 40px;
  height: 40px;
  background-color: #ccc;
  border-radius: 50%;
`;

const Name = styled.div`
  font-size: 16px;
`;

function UserCard({ name, status }) {
  return (
    <Card status={status}>
      <Avatar />
      <Name>{name}</Name>
    </Card>
  );
}

export default UserCard;

步骤 3:在 App.js 中使用(和上面一样)

import UserCard from './components/UserCardStyled'; // 改个路径就行

function App() {
  return (
    <div>
      <UserCard name="张三" status="online" />
      <UserCard name="李四" status="offline" />
    </div>
  );
}

✅ 优点:状态逻辑直接写在样式里,不用记一堆类名
❌ 缺点:多装了一个库,代码看起来“不像 CSS”

💡 我当初第一次看到 ${props => ...} 时懵了,以为是模板字符串错误。其实这是 styled-components 的“插值”语法,专门用来动态传值。


五、新手常问的5个问题

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

:日常项目几乎没影响。只有在极端场景(比如渲染上千个动态组件)才需要考虑。React 本身开销比这个大得多。

Q2:传统 CSS 能不能做到局部作用域?

:可以!用 CSS Modules:

// UserCard.module.css
.card { /* ... */ }
import styles from './UserCard.module.css';
<div className={styles.card}></div>

这样类名会被自动哈希化,避免冲突。很多团队用它替代 CSS-in-JS。

Q3:爬虫能看到 CSS-in-JS 生成的样式吗?

:能!因为最终都会变成 <style> 标签插入 HTML。搜索引擎爬虫(包括 Google)都能正常解析。不用担心 SEO。

🕵️‍♂️ 顺便澄清:这里说的“爬虫”是指搜索引擎爬虫,不是你自己写的 Python 爬虫。如果是后者,只要页面能渲染出来,样式对数据抓取没影响。

Q4:我该学哪种?

  • 如果你刚学 React,先掌握传统 CSS + CSS Modules,打好基础
  • 如果你做复杂交互(比如主题切换、动态皮肤),再学 CSS-in-JS
  • 大厂面试常问区别,但实际工作中两种都可能用到

Q5:有没有“最好”的方案?

:没有!甚至还有人用 Sass、Less、Tailwind CSS……
关键不是工具,而是理解“为什么需要这个方案”。比如:

  • 全局样式(如 reset.css)→ 传统 CSS
  • 组件私有样式 → CSS-in-JS 或 CSS Modules
  • 快速原型 → Tailwind 这类原子化 CSS

六、给初学者的学习建议

  1. 别追求“最新”:技术圈总吹新方案,但传统 CSS 永远不会淘汰。先学会走路,再学跑。
  2. 动手比看文档重要:照着本文的代码敲一遍,比读十篇理论文章有用。
  3. 遇到报错别慌:90% 的问题都是拼写错误或忘了 import。仔细看控制台红字。
  4. 不要过早优化:小项目用哪种都行,等项目大了再重构也不迟。
  5. 关注“解决问题”:样式方案只是工具,目标是做出好用的界面。

七、下一步怎么学?

如果你已经跑通了上面的例子,可以尝试:

  1. 加个“主题切换”功能:用 CSS-in-JS 实现暗黑模式,体会动态样式的威力
  2. 试试 CSS Modules:把传统 CSS 示例改成模块化写法
  3. 看看 Tailwind CSS:另一种现代方案,写 class 就能出样式
  4. 读官方文档

最后送大家一句话:“工具没有银弹,只有合适与否。”

我带过的新人里,最快上手的不是技术最强的,而是愿意动手、不怕犯错、懂得根据场景选择工具的人。希望你也是!

有问题欢迎留言,我会一一回复。祝你前端之路越走越顺!

评论 0

最热最新
暂无评论
网络唐志强爱好者Lv.1
0
影响力
0
文章
0
粉丝