REACT_CSS_COMPARISON.md 11 KB

React CSS 方案对比:SCSS vs React CSS-in-JS

🎯 核心问题

SCSS 比 React 的 CSS 还强大吗?React 还有更厉害的 CSS 吗?

答案: React 有很多更强大的 CSS 方案,它们各有优势。SCSS 是预处理器,而 React 的 CSS-in-JS 是运行时/编译时方案,功能更强大。


📊 方案对比总览

方案 类型 学习曲线 性能 功能强大度 流行度
SCSS 预处理器 ⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
CSS Modules 编译时 ⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐
Styled Components CSS-in-JS ⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
Emotion CSS-in-JS ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
Tailwind CSS 工具类 ⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
StyleX 零运行时 ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐

1. SCSS(你当前使用的)

特点

  • 预处理器:编译时转换为 CSS
  • 功能强大:变量、嵌套、函数、混入等
  • 性能好:编译后就是普通 CSS
  • 生态成熟:插件和工具丰富

代码示例

// device.scss
$primary-color: #0769fb;

.device-container {
  background-color: $primary-color;
  
  .device-update {
    padding: 16px;
  }
}
// device.jsx
import './device.scss'

function Device() {
  return <div className="device-container">...</div>
}

优势

  • ✅ 编译时处理,运行时性能好
  • ✅ 功能完整(变量、函数、循环等)
  • ✅ 学习成本低
  • ✅ 浏览器兼容性好

劣势

  • ❌ 无法在 JS 中动态修改样式
  • ❌ 无法根据 props 动态生成样式
  • ❌ 样式和组件分离

2. CSS Modules(编译时方案)

特点

  • 局部作用域:自动生成唯一类名
  • 类型安全:TypeScript 支持好
  • 性能优秀:编译时处理
  • 零运行时开销

代码示例

/* device.module.css */
.container {
  background-color: #0769fb;
}

.title {
  font-size: 20px;
}
// device.jsx
import styles from './device.module.css'

function Device() {
  return (
    <div className={styles.container}>
      <h1 className={styles.title}>设备</h1>
    </div>
  )
}

优势

  • ✅ 自动作用域隔离,避免样式冲突
  • ✅ 性能好,编译时处理
  • ✅ TypeScript 支持好
  • ✅ 可以配合 SCSS 使用

劣势

  • ❌ 无法动态修改样式
  • ❌ 需要手动管理类名

3. Styled Components(CSS-in-JS)⭐ 最流行

特点

  • CSS-in-JS:样式写在 JS 中
  • 动态样式:根据 props 动态生成
  • 组件化:样式和组件绑定
  • 主题支持:内置主题系统

安装

npm install styled-components

代码示例

import styled from 'styled-components'

// 创建样式组件
const DeviceContainer = styled.div`
  width: 100%;
  height: 100%;
  background-color: ${props => props.bgColor || '#0769fb'};
  display: flex;
  align-items: center;
  justify-content: center;
  
  &:hover {
    background-color: ${props => props.hoverColor || '#0550d0'};
  }
`

const Title = styled.h1`
  font-size: ${props => props.size || '20px'};
  color: ${props => props.theme.primaryColor};
`

// 使用
function Device({ isActive }) {
  return (
    <DeviceContainer 
      bgColor={isActive ? '#28a745' : '#0769fb'}
      hoverColor="#0550d0"
    >
      <Title size="24px">设备列表</Title>
    </DeviceContainer>
  )
}

// 主题支持
const theme = {
  primaryColor: '#0769fb',
  spacing: '16px'
}

function App() {
  return (
    <ThemeProvider theme={theme}>
      <Device />
    </ThemeProvider>
  )
}

优势

  • 动态样式:根据 props/state 动态生成
  • 组件化:样式和组件绑定,易维护
  • 主题系统:内置主题支持
  • TypeScript 支持好
  • 自动处理浏览器前缀

劣势

  • ❌ 运行时开销(但很小)
  • ❌ 学习曲线较陡
  • ❌ 调试稍困难(生成的类名)

4. Emotion(CSS-in-JS)⭐ 性能更好

特点

  • 性能优化:比 styled-components 更快
  • 灵活:支持多种写法
  • 体积小:247KB
  • React 18 支持好

安装

npm install @emotion/react @emotion/styled

代码示例

import { css } from '@emotion/react'
import styled from '@emotion/styled'

// 方式1:css prop
const containerStyle = css`
  width: 100%;
  background-color: #0769fb;
  
  &:hover {
    background-color: #0550d0;
  }
`

function Device() {
  return <div css={containerStyle}>设备</div>
}

// 方式2:styled components
const DeviceContainer = styled.div`
  width: 100%;
  background-color: ${props => props.bgColor};
  
  &:hover {
    transform: scale(1.05);
  }
`

// 方式3:动态样式
function Device({ isActive }) {
  return (
    <div
      css={css`
        background-color: ${isActive ? '#28a745' : '#0769fb'};
        transition: all 0.3s;
      `}
    >
      设备
    </div>
  )
}

优势

  • ✅ 性能比 styled-components 好
  • ✅ 支持多种写法
  • ✅ 体积更小
  • ✅ SSR 支持好

劣势

  • ❌ 社区相对较小
  • ❌ 文档不如 styled-components 完善

5. Tailwind CSS(工具类)⭐ 最流行

特点

  • 工具类:预定义的 CSS 类
  • 按需生成:只生成使用的样式
  • 性能极佳:编译时处理
  • 开发速度快:无需写 CSS

安装

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

代码示例

// 纯工具类
function Device() {
  return (
    <div className="w-full h-full bg-blue-500 flex items-center justify-center hover:bg-blue-600 transition-colors">
      <h1 className="text-white text-2xl font-bold">设备列表</h1>
    </div>
  )
}

// 配合 CSS Modules
// device.module.css
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .device-card {
    @apply bg-blue-500 p-4 rounded-lg shadow-lg;
  }
}

优势

  • 开发速度快:无需写 CSS
  • 性能好:按需生成
  • 一致性:设计系统统一
  • 体积小:只包含使用的样式
  • 学习成本低

劣势

  • ❌ HTML 类名可能很长
  • ❌ 需要记忆工具类
  • ❌ 复杂动画需要额外配置

6. StyleX(Meta 零运行时)

特点

  • 零运行时:编译时转换为 CSS
  • 类型安全:TypeScript 支持好
  • 性能最佳:无运行时开销
  • Meta 开发:Facebook 出品

安装

npm install @stylexjs/stylex

代码示例

import stylex from '@stylexjs/stylex'

const styles = stylex.create({
  container: {
    width: '100%',
    backgroundColor: '#0769fb',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
  },
  title: {
    fontSize: '20px',
    color: 'white',
  },
})

function Device() {
  return (
    <div {...stylex.props(styles.container)}>
      <h1 {...stylex.props(styles.title)}>设备</h1>
    </div>
  )
}

优势

  • ✅ 零运行时开销
  • ✅ 类型安全
  • ✅ 性能最佳
  • ✅ Meta 支持

劣势

  • ❌ 相对较新,生态不成熟
  • ❌ 学习曲线陡
  • ❌ 文档较少

🎯 功能对比

动态样式(根据 props/state)

方案 支持度
SCSS ❌ 不支持
CSS Modules ❌ 不支持
Styled Components ✅✅✅ 完全支持
Emotion ✅✅✅ 完全支持
Tailwind CSS ⚠️ 需要配合 JS
StyleX ✅ 支持

主题支持

方案 支持度
SCSS ⚠️ 需要手动实现
CSS Modules ⚠️ 需要手动实现
Styled Components ✅✅✅ 内置支持
Emotion ✅✅✅ 内置支持
Tailwind CSS ✅ 配置支持
StyleX ⚠️ 需要手动实现

性能

方案 运行时开销 编译时优化
SCSS ✅ 无 ✅ 是
CSS Modules ✅ 无 ✅ 是
Styled Components ⚠️ 有 ❌ 否
Emotion ⚠️ 有(较小) ⚠️ 部分
Tailwind CSS ✅ 无 ✅ 是
StyleX ✅ 无 ✅ 是

TypeScript 支持

方案 支持度
SCSS ⚠️ 基础
CSS Modules ✅✅✅ 完美
Styled Components ✅✅✅ 完美
Emotion ✅✅✅ 完美
Tailwind CSS ✅✅ 很好
StyleX ✅✅✅ 完美

💡 实际应用示例对比

场景:根据状态动态改变样式

SCSS(不支持动态)

// 需要写多个类
.device-active { background: #28a745; }
.device-inactive { background: #0769fb; }
<div className={isActive ? 'device-active' : 'device-inactive'}>

Styled Components(完全支持)

const Device = styled.div`
  background-color: ${props => props.isActive ? '#28a745' : '#0769fb'};
  transition: all 0.3s;
`

<Device isActive={isActive}>设备</Device>

Tailwind CSS(需要配合 JS)

<div className={`${isActive ? 'bg-green-500' : 'bg-blue-500'} transition-colors`}>

🏆 推荐方案

1. 小型项目 → SCSS

  • ✅ 简单直接
  • ✅ 性能好
  • ✅ 学习成本低

2. 中型项目 → CSS Modules + SCSS

  • ✅ 作用域隔离
  • ✅ 性能好
  • ✅ TypeScript 支持好

3. 大型项目(需要动态样式) → Styled Components / Emotion

  • ✅ 动态样式支持
  • ✅ 主题系统
  • ✅ 组件化

4. 快速开发 → Tailwind CSS

  • ✅ 开发速度快
  • ✅ 性能好
  • ✅ 设计系统统一

5. 性能优先 → StyleX

  • ✅ 零运行时
  • ✅ 性能最佳
  • ✅ 类型安全

📝 总结

SCSS vs React CSS-in-JS

特性 SCSS React CSS-in-JS
动态样式
组件绑定
主题系统 ⚠️
运行时性能 ⚠️
编译时性能 ⚠️
学习曲线 ⭐⭐ ⭐⭐⭐
功能强大度 ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐

结论

  1. SCSS 是预处理器,功能强大但无法动态修改样式
  2. React CSS-in-JS(Styled Components/Emotion) 更强大,支持动态样式、主题、组件绑定
  3. Tailwind CSS 适合快速开发,性能好
  4. StyleX 性能最佳,但生态不成熟

建议:

  • 如果不需要动态样式 → 继续用 SCSS
  • 如果需要动态样式和主题 → 使用 Styled Components 或 Emotion
  • 如果追求性能 → 使用 Tailwind CSS 或 StyleX

🚀 迁移建议

从 SCSS 迁移到 Styled Components

// 之前:SCSS
// device.scss
.device-container {
  background-color: $primary-color;
}

// device.jsx
import './device.scss'
<div className="device-container">

// 之后:Styled Components
import styled from 'styled-components'

const DeviceContainer = styled.div`
  background-color: ${props => props.theme.primaryColor};
`

<DeviceContainer>

混合使用(推荐)

// 全局样式用 SCSS
import './global.scss'

// 组件样式用 Styled Components
const Button = styled.button`...`

📚 学习资源