入门

升级指南

将您的 Tailwind CSS 项目从 v3 升级到 v4。

Tailwind CSS v4.0 是框架的新主要版本,虽然我们努力减少破坏性变更,但某些更新是必要的。本指南概述了将您的项目从 v3 升级到 v4 所需的所有步骤。

Tailwind CSS v4.0 设计用于 Safari 16.4+、Chrome 111+ 和 Firefox 128+。 如果您需要支持旧版浏览器,请在浏览器支持要求变更之前继续使用 v3.4。

使用升级工具

如果您想将项目从 v3 升级到 v4,可以使用我们的升级工具来处理大部分繁重工作:

Terminal
$ npx @tailwindcss/upgrade

对于大多数项目,升级工具会自动完成整个迁移过程,包括更新依赖项、将配置文件迁移到 CSS,以及处理模板文件的任何变更。

升级工具需要 Node.js 20 或更高版本,因此请确保在运行之前更新您的环境。

我们建议在新分支中运行升级工具,然后仔细检查差异并在浏览器中测试您的项目,以确保所有更改都是正确的。在复杂项目中,您可能需要手动调整一些内容,但无论如何,该工具都将为您节省大量时间。

此外,查看 v4 中的所有 破坏性变更 也是一个好主意,以了解变更的具体情况,以防您需要在升级工具未捕获的情况下更新项目中的其他内容。

手动升级

使用 PostCSS

在 v3 中,tailwindcss 包是一个 PostCSS 插件,但在 v4 中,PostCSS 插件位于专用的 @tailwindcss/postcss 包中。

此外,在 v4 中,导入和供应商前缀现在会自动处理,因此如果您的项目中有 postcss-importautoprefixer,可以将其移除:

postcss.config.mjs
export default {  plugins: {    "postcss-import": {},    tailwindcss: {},    autoprefixer: {},    "@tailwindcss/postcss": {},  },};

使用 Vite

如果您在使用 Vite,我们建议从 PostCSS 插件迁移到我们新的专用 Vite 插件,以提高性能和开发体验:

vite.config.ts
import { defineConfig } from "vite";import tailwindcss from "@tailwindcss/vite";export default defineConfig({  plugins: [    tailwindcss(),  ],});

使用 Tailwind CLI

在 v4 中,Tailwind CLI 位于专用的 @tailwindcss/cli 包中。更新您的构建命令以改用新包:

Terminal
npx tailwindcss -i input.css -o output.cssnpx @tailwindcss/cli -i input.css -o output.css

从 v3 的变更

下面是 Tailwind CSS v4.0 中所有破坏性变更的综合列表。

我们的 升级工具 将自动处理大部分这些变更,因此如果您可以使用它,我们强烈推荐您使用。

浏览器要求

Tailwind CSS v4.0 旨在支持现代浏览器,目标为 Safari 16.4、Chrome 111 和 Firefox 128。我们依赖现代 CSS 特性,如 @propertycolor-mix() 来实现核心框架特性,Tailwind CSS v4.0 将不支持旧版浏览器。

如果您需要支持旧版浏览器,我们建议暂时坚持使用 v3.4。我们正在积极探索兼容模式,以帮助人们更早地升级,我们希望在未来分享更多消息。

移除 @tailwind 指令

在 v4 中,您通过常规 CSS @import 语句导入 Tailwind,而不是使用您在 v3 中使用的 @tailwind 指令:

CSS
@tailwind base;@tailwind components;@tailwind utilities;@import "tailwindcss";

移除的弃用工具

我们已删除在 v3 中被弃用并且多年未记录的任何工具。以下是移除的内容及其现代替代方案的列表:

弃用替代
bg-opacity-*使用透明度修饰符,如 bg-black/50
text-opacity-*使用透明度修饰符,如 text-black/50
border-opacity-*使用透明度修饰符,如 border-black/50
divide-opacity-*使用透明度修饰符,如 divide-black/50
ring-opacity-*使用透明度修饰符,如 ring-black/50
placeholder-opacity-*使用透明度修饰符,如 placeholder-black/50
flex-shrink-*shrink-*
flex-grow-*grow-*
overflow-ellipsistext-ellipsis
decoration-slicebox-decoration-slice
decoration-clonebox-decoration-clone

改名的工具

我们在 v4 中对以下工具进行了改名,以使其更加一致和可预测:

v3v4
shadow-smshadow-xs
shadowshadow-sm
drop-shadow-smdrop-shadow-xs
drop-shadowdrop-shadow-sm
blur-smblur-xs
blurblur-sm
backdrop-blur-smbackdrop-blur-xs
backdrop-blurbackdrop-blur-sm
rounded-smrounded-xs
roundedrounded-sm
outline-noneoutline-hidden
ringring-3

更新的影子、半径和模糊规模

我们已更改默认影子、半径和模糊规模的名称,以确保每个工具都有命名值。“裸”版本仍然可以为了向后兼容,但 <utility>-sm 工具的外观将不同,除非更新为各自的 <utility>-xs 版本。

要使您的项目更新这些变更,请将所有 v3 工具替换为其 v4 版本:

HTML
<input class="shadow-sm" /><input class="shadow-xs" /><input class="shadow" /><input class="shadow-sm" />

重命名轮廓工具

outline 工具现在默认设置 outline-width: 1px,以使其与边框和环工具更加一致。此外,所有 outline-<number> 工具默认将 outline-style 设置为 solid,省去了与 outline 组合的需要:

HTML
<input class="outline outline-2" /><input class="outline-2" />

之前的 outline-none 工具实际上并未设置 outline-style: none,而是设置了一个不可见的轮廓,仍然会在强制颜色模式下显示,以满足可访问性原因。

为了解释这一点,我们将此工具重命名为 outline-hidden,并添加了一个新的 outline-none 工具,实际设置 outline-style: none

要使您的项目更新这一变更,请将任何对 outline-none 的使用替换为 outline-hidden

HTML
<input class="focus:outline-none" /><input class="focus:outline-hidden" />

默认环宽度变更

在 v3 中,ring 工具添加了一个 3px 的环。在 v4 中我们将其改为 1px,以使其与边框和轮廓一致。

要使您的项目更新此变更,请将任何对 ring 的使用替换为 ring-3

HTML
<input class="ring ring-blue-500" /><input class="ring-3 ring-blue-500" />

空间选择器的变更

我们更改了 space-x-*space-y-* 工具 使用的选择器,以解决大页面上的严重性能问题:

CSS
/* 之前 */.space-y-4 > :not([hidden]) ~ :not([hidden]) {  margin-top: 1rem;}/* 现在 */.space-y-4 > :not(:last-child) {  margin-bottom: 1rem;}

如果您之前使用这些工具与行内元素,或如果您为子元素添加其他边距以调整它们的间距,您的项目可能会看到变更。

如果此变化在您的项目中造成任何问题,我们建议迁移到 Flex 或 Grid 布局并改用 gap

HTML
<div class="space-y-4 p-4"><div class="flex flex-col gap-4 p-4">  <label for="name">名称</label>  <input type="text" name="name" /></div>

Divide 选择器

我们更改了 divide-x-*divide-y-* 工具 使用的选择器,以解决大页面上的严重性能问题:

CSS
/* 之前 */.divide-y-4 > :not([hidden]) ~ :not([hidden]) {  border-top-width: 4px;}/* 现在 */.divide-y-4 > :not(:last-child) {  border-bottom-width: 4px;}

如果您曾经与行内元素一起使用这些工具,或为子元素添加其他边距/内边距以调整其间距,或调整特定子元素的边框,您的项目可能会看到变化。

在渐变中使用变体

在 v3 中,使用变体覆盖渐变的部分会“重置”整个渐变,因此在此示例中,暗模式下的 to-* 颜色会变成透明,而不是黄色:

HTML
<div class="bg-gradient-to-r from-red-500 to-yellow-400 dark:from-blue-500">  <!-- ... --></div>

在 v4 中,这些值会被保留,这与 Tailwind 中其他工具的工作方式更加一致。

这意味着如果您想在特定状态下将三段渐变“重置”为两段渐变,您可能需要明确使用 via-none

HTML
<div class="bg-linear-to-r from-red-500 via-orange-400 to-yellow-400 dark:via-none dark:from-blue-500 dark:to-teal-400">  <!-- ... --></div>

容器配置

在 v3 中,container 工具有几个配置选项,如 centerpadding,在 v4 中不再存在。

要自定义 v4 中的 container 工具,请使用 @utility 指令扩展它:

CSS
@utility container {  margin-inline: auto;  padding-inline: 2rem;}

默认边框颜色

在 v3 中,border-*divide-* 工具默认使用您配置的 gray-200 颜色。我们在 v4 中将其更改为 currentColor,以减少 Tailwind 的主观性并匹配浏览器的默认值。

要使您的项目更新此变更,请确保在使用 border-*divide-* 工具的地方指定颜色:

<div class="border border-gray-200 px-2 py-3 ...">  <!-- ... --></div>

或者,您可以将这些基础样式添加到项目中,以保留 v3 行为:

CSS
@layer base {  *,  ::after,  ::before,  ::backdrop,  ::file-selector-button {    border-color: var(--color-gray-200, currentColor);  }}

默认环宽和颜色

我们已将 ring 工具的宽度从 3px 更改为 1px,并将默认颜色从 blue-500 更改为 currentColor,以使其与 border-*divide-*outline-* 工具更加一致。

要使您的项目更新这些变更,请将任何对 ring 的使用替换为 ring-3

<button class="focus:ring ..."><button class="focus:ring-3 ...">  <!-- ... --></button>

然后确保在依赖默认环颜色的地方添加 ring-blue-500

<button class="focus:ring-3 focus:ring-blue-500 ...">  <!-- ... --></button>

或者,将这些主题变量添加到您的 CSS 中,以保留 v3 行为:

CSS
@theme {  --default-ring-width: 3px;  --default-ring-color: var(--color-blue-500);}

请注意,这些变量仅在兼容性方面得到支持,并且不被视为 Tailwind CSS v4.0 的规范用法。

Preflight 变更

我们在 v4 中对 Preflight 的基础样式进行了一些小的更改:

新的默认占位符颜色

在 v3 中,默认情况下占位符文本使用您配置的 gray-400 颜色。我们在 v4 中将其简化为仅使用当前文本颜色的 50% 不透明度。

您可能根本不会注意到此变化(这甚至可能使您的项目看起来更好),但如果您想保留 v3 行为,可以将此 CSS 添加到项目中:

CSS
@layer base {  input::placeholder,  textarea::placeholder {    color: var(--color-gray-400);  }}

按钮使用默认光标

按钮现在使用 cursor: default,而不是 cursor: pointer,以匹配默认浏览器行为。

如果您希望继续默认使用 cursor: pointer,请将这些基础样式添加到您的 CSS 中:

CSS
@layer base {  button:not(:disabled),  [role="button"]:not(:disabled) {    cursor: pointer;  }}

对话框边距被移除

Preflight 现在将 <dialog> 元素的边距重置为与其他元素的一致性。

如果您仍希望对话框默认居中,可以将此 CSS 添加到项目中:

CSS
@layer base {  dialog {    margin: auto;  }}

隐藏属性优先

blockflex 这样的显示类不再优先于元素上的 hidden 属性。如果您希望元素对用户可见,请移除 hidden 属性。请注意,这不适用于 hidden="until-found"

使用前缀

前缀现在看起来像变体,并且始终位于类名的开头:

<div class="tw:flex tw:bg-red-500 tw:hover:bg-red-600">  <!-- ... --></div>

使用前缀时,您仍应根据不使用前缀的情况配置主题变量:

@import "tailwindcss" prefix(tw);@theme {  --font-display: "Satoshi", "sans-serif";  --breakpoint-3xl: 120rem;  --color-avocado-100: oklch(0.99 0 0);  --color-avocado-200: oklch(0.98 0.04 113.22);  --color-avocado-300: oklch(0.94 0.11 115.03);  /* ... */}

生成的 CSS 变量 包含一个前缀,以避免与您项目中的现有变量冲突:

:root {  --tw-font-display: "Satoshi", "sans-serif";  --tw-breakpoint-3xl: 120rem;  --tw-color-avocado-100: oklch(0.99 0 0);  --tw-color-avocado-200: oklch(0.98 0.04 113.22);  --tw-color-avocado-300: oklch(0.94 0.11 115.03);  /* ... */}

The important modifier

在 v3 中,您可以通过在实用程序名称开头(但在任何变体之后)放置 ! 来标记实用程序为重要。在 v4 中,您应该将 ! 放在类名的末尾:

<div class="flex! bg-red-500! hover:bg-red-600/50!">  <!-- ... --></div>

旧方式仍然支持以兼容性,但已被弃用。

添加自定义工具

在 v3 中,您在 @layer utilities@layer components 中定义的任何自定义类都会被 Tailwind 识别为真正的实用程序类,并且会自动支持像 hoverfocuslg 这样的变体,区别在于 @layer components 总是在生成的样式表中优先出现。

在 v4 中,我们使用原生层叠层(cascade layers),不再劫持 @layer 规则,因此引入了 @utility API 作为替代:

CSS
@layer utilities {  .tab-4 {    tab-size: 4;  }}@utility tab-4 {  tab-size: 4;}

自定义工具现在也会根据其定义的属性数量进行排序。这意味着像 .btn 这样的组件工具可以被其他 Tailwind 工具覆盖,而无需额外配置:

CSS
@layer components {  .btn {    border-radius: 0.5rem;    padding: 0.5rem 1rem;    background-color: ButtonFace;  }}@utility btn {  border-radius: 0.5rem;  padding: 0.5rem 1rem;  background-color: ButtonFace;}

了解有关在 添加自定义工具文档 中注册自定义工具的更多信息。

变体堆叠顺序

在 v3 中,堆叠的变体是从右向左应用,但在 v4 中,我们已更新为从左向右应用,以更类似 CSS 的语法。

要更新您的项目以适应此变更,请反转项目中任何对变体堆叠顺序敏感的顺序:

HTML
<ul class="py-4 first:*:pt-0 last:*:pb-0"><ul class="py-4 *:first:pt-0 *:last:pb-0">  <li></li>  <li></li>  <li></li></ul>

如果您使用了这些变体,数量可能非常少 —— 直接子变体(*)和任何排版插件变体(prose-headings)是最可能使用的,且仅在它们与其他变体堆叠时才需要注意。

在任意值中使用变量

在 v3 中,您可以在没有 var() 的情况下将 CSS 变量用作任意值,但最近的 CSS 更新使这通常会引起歧义,因此我们在 v4 中相应更改了语法,使用圆括号代替方括号。

要更新项目,请将旧变量简写语法替换为新的变量简写语法:

HTML
<div class="bg-[--brand-color]"></div><div class="bg-(--brand-color)"></div>

网格和 object-position 工具中的任意值

在任意值中,grid-cols-*grid-rows-*object-* 工具之前会将逗号替换为空格。这种特殊处理在 Tailwind CSS v3 中是为了向 v2 保持兼容。在 v4.0 中,这种兼容性已取消,必须使用下划线表示空格。

要针对该更改更新项目,请将逗号替换为下划线:

HTML
<div class="grid-cols-[max-content,auto]"></div><div class="grid-cols-[max-content_auto]"></div>

移动端的悬停样式

在 v4 中,我们更新了 hover 变体,仅在主要输入设备支持悬停时才应用:

CSS
@media (hover: hover) {  .hover\:underline:hover {    text-decoration: underline;  }}

如果您的网站依赖触摸设备的点击触发悬停,这可能造成问题。如果是这样,您可以使用自定义变体覆盖 hover,使用旧实现:

CSS
@custom-variant hover (&:hover);

一般建议将悬停视为一种增强,而非必须,因为触摸设备无法真正悬停。

过渡轮廓颜色

transitiontransition-colors 工具现在包含 outline-color 属性。

这意味着如果您为焦点状态设置了自定义轮廓颜色,颜色将从默认颜色过渡。为避免该问题,请确保无条件设置轮廓颜色,或对两种状态都显式设置:

HTML
<button class="transition hover:outline-2 hover:outline-cyan-500"></button><button class="outline-cyan-500 transition hover:outline-2"></button>

独立的变换属性

rotate-*scale-*translate-* 工具现在基于 CSS 中的独立 rotatescaletranslate 属性。通常不会影响行为,但有几点需要注意:

重置变换

之前您可以通过 transform-none 重置旋转、缩放和平移工具。现在不行,需分别重置各个属性:

HTML
<button class="scale-150 focus:transform-none"></button><button class="scale-150 focus:scale-none"></button>

过渡

如果您自定义了过渡属性列表并包含 transform(例如 transition-[opacity,transform]),则这些工具将不再过渡。请改为使用单独属性。如需对 opacity-*scale-* 使用过渡,应使用 transition-[opacity,scale]

HTML
<button class="hover:scale-150 transition-[opacity,transform]"></button><button class="hover:scale-150 transition-[opacity,scale]"></button>

禁用核心插件

在 v3 中,存在 corePlugins 选项可完全禁用某些工具,v4 不再支持。

使用 theme() 函数

由于 v4 为所有主题值生成了 CSS 变量,我们建议尽可能使用这些变量,而非 theme() 函数:

CSS
.my-class {  background-color: theme(colors.red.500);  background-color: var(--color-red-500);}

仍需用到 theme() 的情况(如 CSS 变量不支持的媒体查询),应使用 CSS 变量名而非旧点表示法:

CSS
@media (width >= theme(screens.xl)) {@media (width >= theme(--breakpoint-xl)) {  /* ... */}

使用 JavaScript 配置文件

出于向后兼容,JavaScript 配置文件在 v4 中仍支持,但不再自动检测。

若仍需使用 JS 配置,可通过 @config 指令显式加载:

CSS
@config "../../tailwind.config.js";

JS 配置中的 corePluginssafelistseparator 选项在 v4.0 中不支持。请使用 @source inline() 实现工具的安全列举。

JavaScript 中的主题值

在 v3 中,我们导出了 resolveConfig 函数,可将 JS 配置转换为平铺对象。

v4 中删除此功能,建议直接使用生成的 CSS 变量,更简单且显著减小包体积。

例如,流行的 Motion 库支持在 CSS 变量值之间动画:

JSX
<motion.div animate={{ backgroundColor: "var(--color-blue-500)" }} />

若需要在 JS 中访问解析的 CSS 变量值,可使用 getComputedStyle 获取根元素主题变量:

spaghetti.js
let styles = getComputedStyle(document.documentElement);let shadow = styles.getPropertyValue("--shadow-xl");

在 Vue、Svelte 或 CSS 模块中使用 @apply

v4 中,与您主 CSS 文件分开打包的样式表(如 CSS 模块文件、Vue、Svelte 或 Astro 中的 <style> 块等)无法访问其他文件中定义的主题变量、自定义工具和自定义变体。

要在这些环境使用这些定义,请使用 @reference 导入,而无需复制任何 CSS:

Vue
<template>  <h1>你好,世界!</h1></template><style>  @reference "../../app.css";  h1 {    @apply text-2xl font-bold text-red-500;  }</style>

或者,可以直接使用 CSS 主题变量,代替完全使用 @apply,这也提升性能,因为 Tailwind 不需处理这些样式:

Vue
<template>  <h1>你好,世界!</h1></template><style>  h1 {    color: var(--text-red-500);  }</style>

详见使用 Tailwind 和 CSS 模块文档。

使用 Sass、Less 和 Stylus

Tailwind CSS v4.0 并非设计用于与 CSS 预处理器(如 Sass、Less 或 Stylus)配合使用。Tailwind 本身就是您的预处理器——您不应将 Tailwind 与 Sass 一起用,原因与您不应将 Sass 与 Stylus 一起用相同。因此,您不能在 Vue、Svelte、Astro 等中的样式表或 <style> 块中使用 Sass、Less 或 Stylus。

详见兼容性文档了解更多信息。