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

Go语言浪人
2025-06-18 18:43
阅读 739

开篇:什么是 CSS 和 CSS-in-JS?

开篇:什么是 CSS 和 CSS-in-JS?

在网页开发中,CSS(Cascading Style Sheets) 是一种用来美化页面的“语言”。它能让你的网页变得五颜六色、排版整齐、动效丰富。但随着前端技术的发展,出现了一种新的写法 —— CSS-in-JS

那它们之间有什么区别呢?

  • 传统CSS:就是我们常见的那种,在 .css 文件中定义样式,然后通过 linkimport 引入 HTML 或组件。
  • CSS-in-JS:顾名思义,是把 CSS 写在 JavaScript 文件里的一种方式。你可以用 JS 来动态生成样式,比如根据用户行为改变背景颜色。

它们各有优势和适用场景,本教程会带你一步步了解,并帮你做出合适的选择!


环境准备:搭建你的第一个项目

环境准备:搭建你的第一个项目

为了对比这两种方式,我们需要一个基础项目环境。

步骤1:安装 Node.js 和 npm

访问 https://nodejs.org,下载并安装 LTS 版本。安装完成后在命令行运行:

node -v
npm -v

如果显示版本号,说明安装成功。

步骤2:创建 React 项目

我们用流行的框架 React 来演示两种方式的应用:

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

打开浏览器,进入 http://localhost:3000,看到欢迎页面就成功啦!


核心概念:理解关键术语

核心概念:理解关键术语

1. 传统 CSS 的基本使用

我们在项目中添加一个按钮组件,然后通过传统 CSS 给它设置样式。

示例:创建按钮组件

src/TraditionalButton.js 中编写:

import React from 'react';
import './TraditionalButton.css';

function TraditionalButton() {
  return <button className="btn">点击我</button>;
}

export default TraditionalButton;

再创建 CSS 文件 TraditionalButton.css

.btn {
  background-color: #4CAF50;
  color: white;
  padding: 10px 20px;
  border-radius: 5px;
  font-size: 16px;
}

最后在 App.js 中引用它:

import React from 'react';
import TraditionalButton from './TraditionalButton';

function App() {
  return (
    <div>
      <h1>传统CSS按钮示例</h1>
      <TraditionalButton />
    </div>
  );
}

export default App;

刷新页面,你就看到了一个绿色的按钮!

✅ 小结:

  • 使用 className 应用类名
  • CSS 单独文件管理样式
  • 结构清晰,适合入门学习

2. CSS-in-JS 简介:以 styled-components 为例

CSS-in-JS 有很多种库,比如 emotion、styled-components 等。我们以最流行的 styled-components 为例。

安装依赖:

npm install styled-components

示例:用 styled-components 实现按钮

src/StyedButton.js 中写:

import React from 'react';
import styled from 'styled-components';

const Button = styled.button`
  background-color: #2196F3;
  color: white;
  padding: 10px 20px;
  border-radius: 5px;
  font-size: 16px;
`;

function StyedButton() {
  return <Button>带样式的按钮</Button>;
}

export default StyedButton;

修改 App.js 来展示这个按钮:

import React from 'react';
import StyedButton from './StyedButton';

function App() {
  return (
    <div>
      <h1>CSS-in-JS 按钮示例</h1>
      <StyedButton />
    </div>
  );
}

export default App;

刷新页面,你会看到一个蓝色按钮!

✅ 小结:

  • 使用模板字符串写样式
  • 不需要 .css 文件
  • 适合组件封装和复用

实战项目:做一个响应式导航栏

我们将分别用传统CSSCSS-in-JS来实现一个简单的响应式导航栏,体验两者的不同写法。

项目目标:

  • 在桌面端显示完整菜单
  • 在移动端自动收起,变为汉堡菜单按钮
  • 点击菜单按钮可以展开/收起菜单

方式一:传统CSS方式

第一步:创建导航栏组件

新建 src/NavbarTraditional.js

import React, { useState } from 'react';
import './NavbarTraditional.css';

function NavbarTraditional() {
  const [isMobileMenuOpen, setMobileMenuOpen] = useState(false);

  return (
    <nav className="navbar">
      <div className="logo">Logo</div>

      <div className={`menu ${isMobileMenuOpen ? 'active' : ''}`}>
        <a href="/">首页</a>
        <a href="/about">关于我们</a>
        <a href="/contact">联系</a>
      </div>

      <button
        className="menu-toggle"
        onClick={() => setMobileMenuOpen(!isMobileMenuOpen)}
      >
        ☰
      </button>
    </nav>
  );
}

export default NavbarTraditional;

第二步:创建对应的 CSS 文件

NavbarTraditional.css

.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #333;
  color: white;
  padding: 10px 20px;
}

.menu {
  display: flex;
  gap: 15px;
}

.menu a {
  color: white;
  text-decoration: none;
}

.menu-toggle {
  display: none;
  background: none;
  color: white;
  font-size: 24px;
  border: none;
  cursor: pointer;
}

@media (max-width: 768px) {
  .menu {
    position: absolute;
    top: 60px;
    left: 0;
    width: 100%;
    background: #333;
    flex-direction: column;
    align-items: flex-start;
    padding: 10px;
    transition: all 0.3s ease;
    transform: translateY(-100%);
    opacity: 0;
  }

  .menu.active {
    transform: translateY(0);
    opacity: 1;
  }


![前端性能优化图表-2](https://code-guide.oss.shanghai.autogptai.club/common/file/download?name=date2025061818/3efb1f7d-56a9-4051-93db-a385cd736bb2.jpg)


  .menu-toggle {
    display: block;
  }
}

第三步:在 App.js 中使用

import React from 'react';
import NavbarTraditional from './NavbarTraditional';

function App() {
  return (
    <div>
      <NavbarTraditional />
    </div>
  );
}

export default App;

现在你已经完成了一个响应式导航栏,试试缩小浏览器窗口吧!


方式二:CSS-in-JS方式(使用 styled-components)

我们来重写一次这个导航栏,这次全部写在一个文件中,不使用外部 CSS 文件。

创建 src/NavbarStyled.js

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

// 导航栏容器
const Nav = styled.nav`
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #555;
  color: white;
  padding: 10px 20px;
`;

// 菜单链接
const MenuLink = styled.a`
  color: white;
  text-decoration: none;
  margin-right: 15px;
`;

// 菜单区域
const Menu = styled.div`
  display: flex;
  @media (max-width: 768px) {
    position: absolute;
    top: 60px;
    left: 0;
    width: 100%;
    background: #555;
    flex-direction: column;
    align-items: flex-start;
    padding: 10px;
    transition: all 0.3s ease;
    transform: translateY(${props => props.isOpen ? '0' : '-100%'});
    opacity: ${props => props.isOpen ? '1' : '0'};
  }
`;

// 汉堡菜单按钮
const MenuToggle = styled.button`
  background: none;
  color: white;
  font-size: 24px;
  border: none;
  cursor: pointer;
  display: none;

  @media (max-width: 768px) {
    display: block;
  }
`;

function NavbarStyled() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <Nav>
      <div className="logo">Logo</div>
      
      <Menu isOpen={isOpen}>
        <MenuLink href="/">首页</MenuLink>
        <MenuLink href="/about">关于我们</MenuLink>
        <MenuLink href="/contact">联系</MenuLink>
      </Menu>

      <MenuToggle onClick={() => setIsOpen(!isOpen)}>☰</MenuToggle>
    </Nav>
  );
}

export default NavbarStyled;

修改 App.js

import React from 'react';
import NavbarStyled from './NavbarStyled';

function App() {
  return (
    <div>
      <NavbarStyled />
    </div>
  );
}

export default App;

刷新页面,你会发现效果完全一样,只是这次的样式代码都在 JS 文件中!

✅ 总结一下:

对比维度 传统CSS CSS-in-JS
文件结构 多个文件 单文件集中
可维护性 清晰易读 动态更方便
学习曲线 更简单 初期略陡

常见问题解答

Q1:CSS-in-JS 不是把 HTML、CSS、JS 混在一起了吗?这样不好吗?

这是很多人第一次接触 CSS-in-JS 时的第一个疑问。但其实这是一种“逻辑分组”的思想:

  • 按功能划分组件而不是按文件类型
  • 所有与某组件相关的代码都在一起,更容易查找和修改
  • 模块化更强,适合大项目维护

Q2:我要不要一开始就学 CSS-in-JS?

如果你是刚学完 HTML/CSS 的新手,建议先从传统 CSS 入手:

  • 掌握基础的盒子模型、布局方式、选择器等
  • 理解 BEM 命名规范
  • 然后再去尝试 CSS-in-JS

这样你会更容易理解它的优势。

Q3:React 中必须用 CSS-in-JS 吗?

不是必须!React 并不限定你用哪种方式写样式,你可以自由选择:

  • 传统 CSS 文件(.css
  • CSS Modules(模块化 CSS)
  • CSS-in-JS(如 styled-components)
  • Tailwind CSS(工具类优先的写法)

选择最适合你项目的方式就好!


学习建议:接下来怎么学?

如果你对 CSS 已有一定基础,想进一步提升,可以按照以下路径继续学习:

📚 学习路线推荐

  1. 巩固基础

    • 盒子模型、浮动、Flexbox 布局
    • Grid 布局
    • 响应式设计(媒体查询)
  2. 进阶知识

    • CSS 动画
    • BEM 命名规范
    • Sass / SCSS(CSS 扩展语言)
  3. CSS-in-JS 进阶

    • 学习更多流行库(如 Emotion、JSS)
    • 主题系统(theme)
    • 自动化命名机制(避免冲突)
  4. 结合框架实践

    • 在 Vue、React 项目中灵活应用
    • 与设计系统结合(如 Material UI、Chakra UI)

总结

前端性能优化图表-1

通过本教程的学习,你应该已经掌握了:

  • 什么是传统 CSS 和 CSS-in-JS
  • 如何在 React 中使用两者
  • 它们的优缺点和使用场景
  • 如何做出合理的技术选择

记住一句话:没有最好的技术,只有最合适的方案。

初学者可以从传统 CSS 入手,打好基础;当你接触到大型项目或组件化开发时,CSS-in-JS 会让你事半功倍。

希望这篇通俗易懂的指南能帮助你在前端之路越走越远 💪!


字数统计:约2702字

评论 0

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