React 中 CSS 的现状

Chris Coyier - 2021 年 10 月 21 日

我半开玩笑地称 CSS-in-JS 世界为 CSS-in-React。下面列出的许多库理论上可以在非 React 环境中工作——它们通常称之为“框架无关的”——但我猜想它们绝大多数的应用都在 React 项目中。这是因为 React,尽管是一个 UI 驱动的库,却没有特别指定的样式解决方案。Vue 在单文件组件中内置了 style 标签。 Svelte 相同。Angular 也有一个内置的组件范围样式解决方案。对于 React,你需要自己动手。

也许,不超越其核心优势也是 React 的优势。我不知道。但是,您确实需要在 React 项目中选择如何对事物进行样式设置。例如,您可以简单地编写(这完全没有问题)常规的纯文本 vanilla CSS 来为您的 React 项目设置样式。与在所有内容上使用内联 style={{ }} 相比,我建议您采用这种方法。但实际上,选择一个库来帮助处理样式确实有一些很不错的优势。例如:

  • 将样式与组件共同定位
  • 将样式范围限制在组件内
  • 在样式变化中使用 props
  • 在 CSS 语法中使用 JavaScript 能力
  • 主题化

每个库都有自己的奇特功能,这些功能可能是对上述内容的变体,或者可能是该库独有的。

值得注意的是,通过使用一个您在其中编写 JavaScript 样式的库,并不一定意味着您必须在 JavaScript 中发布您的样式。使用“零运行时”一词的库通常指的是这样的概念:样式在构建过程中编译成 CSS,因此您可以像使用其他任何 CSS 一样使用它,这可能对性能更好。

本研究由Frontend Masters支持,Frontend Masters 是 CSS-Tricks 的官方学习合作伙伴。

需要前端开发培训吗?

Frontend Masters 是获得培训的最佳场所。他们提供关于所有最重要的前端技术的课程。有兴趣提升您的 React 技能吗?这里是最棒的选择

在进入列表之前,先说几句提醒

  • 我对这些库中每一个库都没有深入的经验。我曾在实际项目中使用过其中几个,其中使用最多的是 CSS Modules。我不能完全说出每个库的细微差别。下面的演示只是对基本语法的基本演示。
  • 如果我有什么事实错误,或者您想添加更多细节,请在评论区或通过我们的联系表告诉我,我会改进内容。
  • 这篇文章的目的之一是为方便参考提供每个库的工作代码示例。

styled-components

  • 非常流行——可能是最常用的选项。
  • 普及了动态样式的可能性以及使用 props 进行变化的魔力
  • 模板字面量语法感觉很舒适,像 CSS 一样。它似乎鼓励以这种方式使用它,但是它也是可以的文档)使用对象语法。
  • 支持SSR,但它与“零运行时”库不同(这意味着“编译成静态 CSS”。它仍然为任何动态样式提供 JavaScript 运行时。

CSS Modules

  • 非常简单。它所做的只是对样式进行作用域限制,并鼓励将样式与组件共同定位。
  • 它最奇特的功能是组合,它基本上是基于现有类的 mixin。
  • 根本不是运行时的东西——它需要一个构建过程。但它仍然适用于HMR 等。您可以使用 JavaScript 中的样式发布它,或者将其提取到静态 CSS 文件中。它不执行任何动态操作,因此如果您提取 CSS,它将极其“零运行时”。
  • 可以与 Sass 相结合。
  • 内置于 Next.js 中

Emotion

Emotion 是一个专为用 JavaScript 编写 css 样式而设计的库。除了出色的开发人员体验(包括源映射、标签和测试实用程序)外,它还提供了强大而可预测的样式组合。它支持字符串和对象样式。

  • 坦白地说,它与 styled-components 并没有太大的区别,但是这个播客深入探讨了一些性能差异。
  • 支持SSR,但不是零运行时。
  • Glamorous 完全已弃用(我想GlamGlamor 也是吗?)转而支持 Emotion,所以这也算是一个进步。

Stitches

  • Variants API 非常有用且完善。
  • TypeScript 编辑器体验¹
  • 支持主题化并鼓励使用设计令牌方法。
  • Utilities 允许您构建自己的自定义样式缩写。
  • 支持SSR——并且它更接近零运行时,但并非完全如此。它似乎也并非真正生成 CSS 文件,而是有一个函数可以输出 CSS,以便您可以通过 <style> 标签使用 SSR(我认为这对于缓存来说并不理想)。
  • 这里有一个Twitter 线程,其中包含一个诚实的评论。您还可以查看所有对这篇文章的反应

vanilla-extract

  • 我认为 vanilla-extract 支持 SSR,但它不仅仅是支持 SSR,因为它只能通过 SSR 使用,除非您选择特定的“运行时”功能,比如动态主题。这就是“零运行时”的含义:它只编译成静态 CSS 文件。
  • TypeScript 编辑器体验¹。(还可以查看我们最近发表的文章。)
  • Variants API,包括一个Recipes API,它与上面的 Stiches 框架类似。
  • 通过Sprinkles 支持主题和类似实用程序类的方案
  • 我本来想在列表中加入Aphrodite,但是它的创建者正在转向 vanilla-extract,所以现在它可能不是一个好选择,即使它似乎与其他库的功能基本相同。

JSS

  • 有一个 React 特定的集成
  • 具有extend语法
  • 插件 架构

Linaria

  • “零运行时” CSS-in-JS 库的鼻祖。
  • 编译成实际的 CSS 文件,但如果你做动态操作仍然有运行时(至少我认为是这样)。
  • 感觉类似于 styled-components API。
  • 支持关键 CSS

Styled JSX

  • Babel 插件,所以绝对是构建流程的一部分。
  • 在组件中直接使用<style jsx>标签,在想要作用域的嵌套级别上,这是一个巧妙的 API。
  • 缺乏嵌套不是很好 - 你必须重复很多选择器名称。

Goober

  • Goober 值得注意的是它有一个很棒的名字,而且只有 1.25KB,这比其他任何东西都小一个数量级。
  • 几乎与 styled-components 和 Emotion 具有相同的特性集。

有趣的资源

  • Shopify 的关于他们想要切换到的库的研究
  • Facebook正在开发中会议视频),但还没有开源任何东西。它似乎被称为“StyleX” - 并且已经有一个名为“Style9”的库试图匹配这些特性,包括接近零运行时、原子 CSS 输出和 TypeScript 体验。
  • 如果你喜欢以原子风格创作,很多人认为使用 Tailwind(可能使用即时模式)是最好的选择。
  • 可能一个更 React 化的 Tailwind 版本是Styled System,它提供了一堆预配置属性作为样式。
  • Twin 类似于以 React 化的方式使用原子风格创作。
  • 我无法让Compiled 为我工作。我相信那只是我自己的问题,但我放弃了。在我看来,它看起来和 styled-components API 完全一样,只是输出是原子 CSS 类,这确实看起来很酷。
  • 网站CSS in JS Playground 展示了很多示例,包括一些这里没有提到的库,比如FelaRadium等等。天哪,这些东西真是太多了。
  1. 我所说的“TypeScript 编辑器体验”是指库是用 TypeScript 编写的,以利用 TypeScript 最好的特性之一:在代码编辑器中帮助自动完成代码。例如,如果你使用 VS Code 作为你的代码编辑器,并且你写了一组“color”变体,然后在你的 JSX 文件中输入<Button color=",你应该在 VS Code 上下文自动完成菜单中获得一个包含你自己的兼容变体的列表供选择。