开源我们对 Tailwind CSS v4.0 的进展

日期
Tailwind CSS v4.0-alpha

去年夏天在 Tailwind Connect 上,我分享了 Oxide 的预览 - 一个我们一直在开发的用于 Tailwind CSS 的全新高性能引擎,旨在简化开发体验并利用近年来 Web 平台的演变。

这个新引擎最初计划作为 v3.x 版本发布,但即使我们致力于向后兼容性,这仍然感觉像是一个新一代的框架,它应该成为 v4.0。

现在还处于早期阶段,我们还有很多工作要做,但今天我们开源了我们的进展,并标记了第一个公开的v4.0.0-alpha,这样你就可以开始尝试它,并帮助我们在今年晚些时候发布稳定版。

为了保留一些稳定版发布的惊喜,我会尽量简短,但如果你喜欢玩非常早期和实验性的东西,这里应该有足够的信息让你开始。


一个为速度而生的新引擎

这个新引擎是一个从头开始的重写,它利用了我们现在对框架的所有了解,更好地模拟了问题空间,使代码更少,速度更快。

  • 速度提升高达 10 倍 - 我们可以在 105 毫秒内完成 Tailwind CSS 网站的完整构建,而不是 960 毫秒,或者在 55 毫秒内完成 Catalyst UI 工具包的构建,而不是 341 毫秒。
  • 更小的占用空间 - 新引擎的安装尺寸缩小了 35% 以上,即使我们使用了一些更重的原生包,比如我们用 Rust 和 Lightning CSS 重写的部分。
  • 在关键位置使用 Rust - 我们将框架中最昂贵和可并行化的部分迁移到了 Rust,同时为了可扩展性,将框架的核心保留在 TypeScript 中。
  • 一个依赖项 - 新引擎唯一依赖的是 Lightning CSS。
  • 自定义解析器 - 我们编写了自己的 CSS 解析器并设计了适合我们需求的自定义数据结构,这使得我们的解析速度比使用 PostCSS 快两倍以上。

统一的工具链

Tailwind CSS v4 不再只是一个插件 - 它是一个用于处理 CSS 的一体化工具。我们已将 Lightning CSS 直接集成到框架中,因此您无需配置有关 CSS 管道的任何内容。

  • 内置 @import 处理 - 无需设置和配置像 postcss-import 这样的工具。
  • 内置供应商前缀 - 您不再需要将 autoprefixer 添加到您的项目中。
  • 内置嵌套支持 - 无需插件即可扁平化嵌套 CSS,它开箱即用。
  • 语法转换 - 现代 CSS 功能(如 oklch() 颜色和媒体查询范围)被转换为具有更好浏览器支持的语法。

我们仍在发布 PostCSS 插件,但我们也在探索第一方捆绑器插件,并且我们在这个第一个 alpha 版本中发布了一个官方的 Vite 插件,您可以立即试用。


为现代网络而设计

我们正在展望未来,使用 Tailwind CSS v4 构建一个在未来几年内都感觉尖端的框架。

  • 原生级联层 - 我们现在使用真正的 @layer 规则,这解决了我们在过去遇到的许多特异性问题。
  • 明确定义的自定义属性 - 我们使用 @property 来定义我们的内部自定义属性,并具有适当的类型和约束,从而可以执行诸如转换背景渐变之类的操作。
  • 使用 color-mix 进行透明度修饰 — 使用 CSS 变量定义颜色或调整 currentColor 的透明度时,使用我们的透明度修饰语法变得前所未有的简单。
  • 核心中的容器查询 — 我们已将对容器查询的支持直接添加到核心,并使用新的 @min-*@max-* 变体来支持容器查询范围。

我们还在努力使用广色域颜色刷新我们的调色板,并引入对其他现代 CSS 功能的支持,例如 @starting-style、锚点定位等等。


可组合变体

新的架构使得可以将作用于其他选择器的变体组合在一起,例如 group-*peer-*has-*,以及我们在 v4 中引入的新的 not-* 变体。

在早期版本中,像 group-has-* 这样的变体是在框架中明确定义的,但现在 group-* 可以与现有的 has-* 变体组合,而 has-* 变体可以与其他变体(如 focus)组合。

index.html
<div class="group">
  <div class="group-has-[&:focus]:opacity-100">
  <div class="group-has-focus:opacity-100">
    <!-- ... -->
  </div>
</div>

这种可组合性没有限制,你甚至可以编写像 group-not-has-peer-not-data-active:underline 这样的代码,尽管出于某种可怕的原因,你可能需要这样做。


零配置内容检测

你会注意到,至少在这些早期的 alpha 版本中,甚至无法配置你的 content 路径。对于大多数项目来说,你永远不需要再做这件事了——Tailwind 会自动为你找到你的模板文件。

我们使用两种方法之一来实现这一点,具体取决于你将 Tailwind 集成到项目中的方式。

  • 使用 PostCSS 插件或 CLI,Tailwind 会扫描您的整个项目以查找模板文件,使用我们内置的一系列启发式方法来保持速度,例如不扫描 .gitignore 文件中的目录,并忽略二进制文件格式。

  • 使用 Vite 插件,我们依赖于模块图。这很棒,因为我们确切地知道您实际使用了哪些文件,因此它具有最大的性能,并且没有误报或漏报。我们希望将来在 Vite 生态系统之外,使用其他捆绑器插件扩展这种方法。

我们将来肯定会引入一种方法来明确配置内容路径,但我们很好奇这种自动方法对每个人来说效果如何——它在我们自己的项目中运行得很好。


CSS优先配置

Tailwind CSS v4.0 的主要目标是使框架感觉像原生 CSS,而不是像 JavaScript 库。

安装后,您可以使用常规的 CSS @import 语句将其添加到您的项目中

main.css
@import "tailwindcss";

您无需在 JavaScript 配置文件中设置所有自定义项,只需使用 CSS 变量即可

main.css
@import "tailwindcss";

@theme {
  --font-family-display: "Satoshi", "sans-serif";

  --breakpoint-3xl: 1920px;

  --color-neon-pink: oklch(71.7% 0.25 360);
  --color-neon-lime: oklch(91.5% 0.258 129);
  --color-neon-cyan: oklch(91.3% 0.139 195.8);
}

特殊的 @theme 指令告诉 Tailwind 根据这些变量创建新的实用程序和变体,让您在标记中使用诸如 3xl:text-neon-lime 之类的类

index.html
<div class="max-w-lg 3xl:max-w-xl">
  <h1 class="font-display text-4xl">
    Data to <span class="text-neon-cyan">enrich</span> your online business
  </h1>
</div>

添加新的 CSS 变量的行为类似于早期版本框架中的 extend,但您可以通过使用类似 --color-*: initial 的语法清除命名空间来覆盖一组完整的变量,然后再定义所有自定义值

main.css
@import "tailwindcss";

@theme {
  --color-*: initial;

  --color-gray-50: #f8fafc;
  --color-gray-100: #f1f5f9;
  --color-gray-200: #e2e8f0;
  /* ... */
  --color-green-800: #3f6212;
  --color-green-900: #365314;
  --color-green-950: #1a2e05;
}

我们仍在微调一些命名约定,但您可以 在 GitHub 上探索默认主题 以查看哪些内容可供自定义。

如果您不想明确清除默认主题,而是想从头开始,您可以直接导入 "tailwindcss/preflight""tailwindcss/utilities" 来跳过导入默认主题

main.css
@import "tailwindcss";
@import "tailwindcss/preflight" layer(base);
@import "tailwindcss/utilities" layer(utilities);

@theme {
  --color-*: initial;
  --color-gray-50: #f8fafc;
  --color-gray-100: #f1f5f9;
  --color-gray-200: #e2e8f0;
  /* ... */
  --color-green-800: #3f6212;
  --color-green-900: #365314;
  --color-green-950: #1a2e05;
}

我们还将所有主题值作为原生 CSS 变量提供给您的自定义 CSS 中

dist/main.css
:root {
  --color-gray-50: #f8fafc;
  --color-gray-100: #f1f5f9;
  --color-gray-200: #e2e8f0;
  /* ... */
  --color-green-800: #3f6212;
  --color-green-900: #365314;
  --color-green-950: #1a2e05;
}

这使得您可以轻松地在任意值中引用任何主题值,而无需使用 theme() 函数

index.html
<div class="p-[calc(var(--spacing-6)-1px)]">
  <!-- ... -->
</div>

它还使您能够在使用 Framer Motion 等 UI 库时使用主题值,而无需使用 resolveConfig() 函数

JSX
import { motion } from "framer-motion"

export const MyComponent = () => (
  <motion.div
    initial={{ y: 'var(--spacing-8)' }}
    animate={{ y: 0 }}
    exit={{ y: 'var(--spacing-8)' }}
  >
    {children}
  </motion.div>
)

更新内容

我们不会轻易做出重大更改,但目前在 v4 中有一些值得分享的改变。

  • 移除已弃用的实用程序 — 我们移除了很久以前就停止记录的实用程序,例如 text-opacity-*flex-grow-*decoration-slice,取而代之的是它们的现代替代品,例如 text-{color}/*grow-*box-decoration-slice
  • PostCSS 插件和 CLI 是独立的包 — 主 tailwindcss 包不再包含这些,因为并非每个人都需要它们,而是应该使用 @tailwindcss/postcss@tailwindcss/cli 单独安装。
  • 没有默认边框颜色border 实用程序以前默认为 gray-200,但现在它默认为 currentColor,就像浏览器一样。我们做出此更改是为了防止在使用 zincslate 或其他颜色作为主要灰色时,意外地将错误的灰色引入项目。
  • 环默认情况下为 1pxring 实用程序以前默认情况下是 3px 蓝色环,现在它使用 currentColor 的 1px 环。我们发现自己在项目中使用 ring-* 实用程序作为边框的替代方案,并使用 outline-* 用于焦点环,因此我们认为在这里保持一致是一个有益的改变。

还有一些非常底层的实现细节更改,可能会在您的项目中以某种方式出现,但没有像这些更改那样刻意。如果您遇到任何意外情况,请告知我们。


v4.0 路线图

这个新的引擎是一个从头开始的重写,到目前为止,我们一直专注于使用新的配置方法重新构想的开发人员体验。

我们非常重视向后兼容性,这也是我们在今年晚些时候发布稳定版 v4.0 之前需要完成的大部分工作。

  • 支持 JavaScript 配置文件 - 重新引入对经典 tailwind.config.js 文件的兼容性,以便轻松迁移到 v4。
  • 显式内容路径配置 - 使得能够准确地告诉 Tailwind 您的模板位于何处,即使自动内容检测不适合您的设置。
  • 支持其他暗黑模式 - 目前我们只支持使用媒体查询的暗黑模式,还需要重新实现选择器和变体策略。
  • 插件和自定义工具 - 我们还没有支持插件,也没有支持编写自动与变体一起使用的自定义工具。显然,我们将在稳定版发布之前实现这些功能。
  • 前缀支持 - 目前还没有办法为您的类配置前缀,但我们一定会将其带回来。
  • 安全列表和阻止列表 - 目前还无法强制 Tailwind 生成特定类或阻止它生成其他类。
  • 支持 important 配置 - 目前还没有办法使所有工具都生成带有 !important 的代码,但我们计划实现它。
  • 支持 theme() 函数 - 对于新项目来说,这并不需要,因为您现在可以使用 var(),但我们将为了向后兼容性而实现它。
  • 独立 CLI - 我们还没有为新引擎开发独立的 CLI,但绝对会在 v4.0 发布之前完成。

除此之外,我相信我们会发现很多需要修复的错误,一些激动人心的新 CSS 功能需要加入,以及一些需要在正式发布之前进行更多完善的新 API。

我不想对具体的发布时间表做出承诺,但我个人希望在夏季假期开始之前将 v4.0 标记为稳定版。


试用 alpha 版本

我们已经发布了几个 alpha 版本,您可以从今天开始在您的项目中使用它。

如果您使用的是 VS Code 的 Tailwind CSS IntelliSense 扩展,请确保从扩展页面切换到预发布版本,如果您使用的是我们的 Prettier 插件,请确保安装最新版本。

如果您发现问题,请在 GitHub 上告知我们。我们真的希望在发布稳定版本之前,这个东西能够万无一失,报告您发现的任何问题将对我们有很大帮助。

使用 Vite

安装 Tailwind CSS v4 alpha 和我们的新 Vite 插件

$ npm install tailwindcss@next @tailwindcss/vite@next

然后将我们的插件添加到您的 vite.config.ts 文件中

vite-config.ts
import tailwindcss from '@tailwindcss/vite'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [tailwindcss()],
})

最后,在您的主 CSS 文件中导入 Tailwind

app.css
@import "tailwindcss";

使用 PostCSS

安装 Tailwind CSS v4 alpha 和单独的 PostCSS 插件包

$ npm install tailwindcss@next @tailwindcss/postcss@next

然后将我们的插件添加到您的 postcss.config.js 文件中

postcss.config.js
module.exports = {
  plugins: {
    '@tailwindcss/postcss': {}
  }
}

最后,在您的主 CSS 文件中导入 Tailwind

app.css
@import "tailwindcss";

使用 CLI

安装 Tailwind CSS v4 alpha 和单独的 CLI 包

$ npm install tailwindcss@next @tailwindcss/cli@next

接下来,在您的主 CSS 文件中导入 Tailwind

app.css
@import "tailwindcss";

最后,使用 CLI 工具编译您的 CSS

$ npx @tailwindcss/cli@next -i app.css -o dist/app.css