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

Adam Wathan
Tailwind CSS v4.0-alpha

去年夏天在 Tailwind Connect 我分享了 Oxide 的预览——这是一个我们一直在开发的新的高性能引擎,旨在简化开发者体验,并利用近年来网络平台的发展变化。

这个新引擎最初打算作为 v3.x 版本发布,但尽管我们承诺向后兼容,感觉这显然是该框架的新一代,值得标记为 v4.0。

现在还为时已早,我们还有 很多工作要做,但今天我们正在 开源我们的进展,并标记第一个公开的 v4.0.0-alpha,这样你就可以开始尝试并帮助我们在今年晚些时候推出稳定版。

我会尝试简要说明,以保留一些激动人心的内容给稳定版,但如果你喜欢玩非常早期和实验性的东西,这里应该有很多信息可以帮助你入门。


一个为速度构建的新引擎

这个新引擎是从头开始重写的,利用我们现在对框架的全部了解,更好地模型问题空间,减少代码,让事情运行得更快。

  • 速度提升高达 10 倍——我们可以在 105 毫秒内完成 Tailwind CSS 网站的完整构建,而之前需要 960 毫秒,或者我们的 Catalyst UI 套件在 55 毫秒内完成,而之前需要 341 毫秒。
  • 更小的占用空间——新引擎的安装体积减少了 35% 以上,即使我们仍然提供像 Rust 和 Lightning CSS 重写的那部分较重的原生包。
  • 重要部分使用 Rust——我们已将框架中一些最昂贵且可并行处理的部分迁移到 Rust,同时将框架核心保留在 TypeScript 中,以便扩展性。
  • 只有一个依赖——新引擎只依赖于 Lightning CSS。
  • 自定义解析器——我们编写了自己的 CSS 解析器,并设计了适合我们需求的数据结构,使得解析速度比使用 PostCSS 快了 2 倍以上。

统一工具链

Tailwind CSS v4 不再只是一个插件——它是一个一体化的 CSS 处理工具。我们将 Lightning CSS 直接集成到框架中,因此你无需配置任何有关 CSS 流水线的内容。

  • 内置 @import 处理——无需设置和配置像 postcss-import 这样的工具。
  • 内置厂商前缀处理——你再也不用将 autoprefixer 添加到你的项目中。
  • 内置嵌套支持——无须插件即可展平嵌套 CSS,开箱即用。
  • 语法转换——像 oklch() 颜色和媒体查询范围等现代 CSS 特性被转译为具有更好浏览器支持的语法。

我们仍在提供一个 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-* 变体组合,并且可以与像 focus 这样的其他变体组合:

index.html
<div class="group">
<div class="group-has-[&:focus]:opacity-100">
<div class="group-has-focus:opacity-100">
<!-- ... -->
</div>
</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">
用于 <span class="text-neon-cyan">丰富</span> 你的在线业务的数据
</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>

它还使得在使用 UI 库(如 Framer Motion)时,可以使用你的主题值,而无需使用 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 或其他用作主灰色的颜色时。
  • 默认的环宽为 1px——ring 工具的默认值以前是 3px 的蓝色环,现在它是 1px 的 currentColor 环。我们发现自己在项目中使用 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

Get all of our updates directly to your inbox.
Sign up for our newsletter.