- Published on
将 Tailwind CSS 项目从 v3 升级到 v4
- Authors
- Name
- Azimuth Ti
Tailwind CSS v4.0 专为 Safari 16.4+、Chrome 111+ 和 Firefox 128+ 设计。 如果需要支持较旧的浏览器,应坚持使用 v3.4,直到您的浏览器支持要求发生变化,再升级。
Tailwind CSS v4.0 是该框架的新主要版本,项目没有进行重大更改,仅有一些必要更新。这里介绍将项目从 v3 升级到 v4 所需的所有步骤。
使用升级工具
如果您想将项目从 v3 升级到 v4,可以使用官方的的升级工具来完成绝大多数繁重的工作:
$ npx @tailwindcss/upgrade
对于大多数项目,升级工具将自动执行整个迁移过程,包括更新依赖项、将配置文件迁移到 CSS 以及处理对模板文件的任何更改。
升级工具需要 Node.js 20 或更高版本,因此请确保在运行之前更新的环境。
官方建议在新分支中运行升级工具,然后仔细查看差异并在浏览器中测试您的项目,以确保所有更改看起来都正确无误。在复杂的项目中,您可能需要手动调整一些内容,但无论哪种方式,该工具都会为您节省大量时间。
手动升级
使用PostCSS
在 v3 中,tailwindcss
包是一个 PostCSS 插件,但在 v4 中,PostCSS 插件位于专用的@tailwindcss/postcss
包中。
此外,在 v4 中,导入和供应商前缀现在会自动为你处理,因此可以删除 postcss-import 和 autoprefixer(如果它们在你的项目中)
// 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.css
+ npx @tailwindcss/cli -i input.css -o output.css
v4中的所有重大更改
升级工具将自动处理大部分这些更改,因此强烈建议使用升级工具升级项目。
浏览器要求
Tailwind CSS v4.0 专为现代浏览器设计,面向 Safari 16.4、Chrome 111 和 Firefox 128。我们依赖现代 CSS 功能,如 @property
和 color-mix()
来提供核心框架功能,而 Tailwind CSS v4.0 将无法在较旧的浏览器中运行。
如果需要支持较旧的浏览器,建议暂时坚持使用 v3.4。官方正在积极探索一种兼容模式,以帮助人们尽早升级。
删除@tailwind 指令
在 v4 中,使用常规 CSS @import
语句导入 Tailwind,而不是使用在 v3 中使用的 @tailwind
指令:
- @tailwind base;
- @tailwind components;
- @tailwind utilities;
+ @import 'tailwindcss';
删除已经弃用的程序属性
删除了 v3 中已弃用且多年来未记录的所有程序属性。以下是已删除的内容以及现代替代方案的列表:
Deprecated | Replacement |
---|---|
bg-opacity-* | Use 使用不透明度修饰符,如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-ellipsis | text-ellipsis |
decoration-slice | box-decoration-slice |
decoration-clone | box-decoration-clone |
重命名的程序属性
v4 中重命名了以下程序属性,以使其更加一致和可预测:
v3 | v4 |
---|---|
shadow-sm | shadow-xs |
shadow | shadow-sm |
drop-shadow-sm | drop-shadow-xs |
drop-shadow | drop-shadow-sm |
blur-sm | blur-xs |
blur | blur-sm |
backdrop-blur-sm | backdrop-blur-xs |
backdrop-blur | backdrop-blur-sm |
rounded-sm | rounded-xs |
rounded | rounded-sm |
outline-none | outline-hidden |
ring | ring-3 |
更新了shadow、radius、blur scales
官方重命名了默认的shadow、radius、blur scales,以确保每个工具都有一个命名值。“bare”版本仍然适用于向后兼容性,但<utility>-sm
程序属性看起来会有所不同,除非更新到它们各自的<utility>-xs
版本。
要针对这些更改更新项目,请将所有 v3 程序属性替换为其 v4 版本:
- <input class="shadow-sm" />
+ <input class="shadow-xs" />
- <input class="shadow" />
+ <input class="shadow-sm" />
重命名的outline程序属性
现在,outline
程序属性默认将outline-width: 1px
设置为与 border 和 ring 程序属性更加一致。此外,所有outline-<number>
程序属性都将outline-style
默认为solid
,无需将它们与outline
组合在一起:
-<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
:
-<input class="focus:outline-none" />
+<input class="focus:outline-hidden" />
Default ring width change
在 v3 中,ring
程序属性添加了一个3px
的环。我们在 v4 中将其更改为1px
,以使其与边框和轮廓保持一致。
要针对此更改更新您的项目,请将ring
的任何用法替换为ring-3
:
-<input class="ring ring-blue-500" />
+<input class="ring-3 ring-blue-500" />
Space-between selector 间距选择器
我们更改了 space-x-*
和 space-y-*
程序属性使用的选择器,以解决大页面上的严重性能问题:
/* Before */
.space-y-4 > :not([hidden]) ~ :not([hidden]) {
margin-top: 1rem;
}
/* Now */
.space-y-4 > :not(:last-child) {
margin-bottom: 1rem;
}
如果您曾经将这些程序属性与内联元素一起使用,或者如果您向子元素添加其他边距以调整其间距,则可能会在项目中看到更改。
如果此更改导致您的项目出现任何问题,我们建议迁移到 Flex 或 grid 布局,并使用gap
:
-<div class="space-y-4 p-4">
+<div class="flex flex-col gap-4 p-4">
<label for="name">Name</label>
<input type="text" name="name" />
</div>
Using variants with gradients 使用带有渐变的变体
在 v3 中,用变体覆盖渐变的一部分会 “重置” 整个渐变,因此在此示例中,to-\*
颜色在深色模式下将是透明的,而不是黄色的:
<div class="bg-gradient-to-r from-red-500 to-yellow-400 dark:from-blue-500">
<!-- ... -->
</div>
在 v4 中,这些值被保留,这与 Tailwind 中的其他程序属性的工作方式更加一致。
这意味着,如果您想将三档渐变“取消设置”回特定状态下的两档渐变,则可能需要显式使用via-none
:
<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>
Container configuration 容器配置
在 v3 中, container
程序属性具有多个配置选项,例如center
和padding
,这些选项在 v4 中已不存在。
要在 v4 中自定义container
程序属性,请使用@utility
指令对其进行扩展:
@utility container {
margin-inline: auto;
padding-inline: 2rem;
}
Default border color 默认边框颜色
在 v3 中,border-*
和 divide-*
程序属性默认使用您配置的gray-200
颜色。我们在 v4 中将其更改为 currentColor
,以使 Tailwind 不那么固执己见并匹配浏览器默认值。
要针对此更改更新项目,请确保使用 border-*
或 divide-*
程序属性在任意位置指定颜色:
<div class="border border-gray-200 px-2 py-3 ...">
<!-- ... -->
</div>
或者,将这些基本样式添加到您的项目中以保留 v3 行为:
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentColor);
}
}
Default ring width and color
官方已将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 行为:
@theme {
--default-ring-width: 3px;
--default-ring-color: var(--color-blue-500);
}
请注意,这些变量仅出于兼容性原因而受支持,不被视为 Tailwind CSS v4.0 的惯用用法。
Preflight changes
我们在 v4 的 Preflight 中对基本样式进行了一些小的更改:
New default placeholder color 新的默认占位符颜色
在 v3 中,占位符文本默认使用您配置的 gray-400 颜色
。我们在 v4 中对此进行了简化,仅使用不透明度为 50% 的当前文本颜色。
你甚至可能不会注意到这个变化(它甚至可能让你的项目看起来更好),但如果你想保留 v3 的行为,请将这个 CSS 添加到你的项目中:
@layer base {
input::placeholder,
textarea::placeholder {
color: var(--color-gray-400);
}
}
Buttons use the default cursor 按钮使用默认光标
按钮现在使用 cursor: default
而不是 cursor: pointer
来匹配默认浏览器行为。
如果你想默认继续使用 cursor: pointer
,请将这些基本样式添加到你的 CSS 中:
@layer base {
button:not(:disabled),
[role="button"]:not(:disabled) {
cursor: pointer;
}
}
Dialog margins removed 删除对话边距
现在可以重置 <dialog>
元素的边距,使其与其他元素的重置方式一致。
如果您仍希望对话框在默认情况下居中,请将此 CSS 添加到您的项目中:
@layer base {
dialog {
margin: auto;
}
}
Using a prefix 使用前缀
前缀现在看起来像变体,并且始终位于类名的开头:
<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);
/* ... */
}
Adding custom utilities 添加自定义程序属性
在 v3 中,在 @layer utilities
或 @layer components
中定义的任何自定义类都将被 Tailwind 作为真正的程序属性类选取,并将自动与 hover
、focus
或 lg
等变体一起使用,区别在于 @layer components
在生成的样式表中始终排在第一位。
在 v4 中,我们使用原生级联层,不再劫持 @layer
规则,因此我们引入了 @utility
API 作为替代:
-@layer utilities {
- .tab-4 {
- tab-size: 4;
- }
-}
+@utility tab-4 {
+ tab-size: 4;
+}
自定义程序属性现在也根据它们定义的属性数量进行排序。这意味着像这样的 .btn
组件程序属性可以被其他 Tailwind 程序属性覆盖,而无需额外配置:
-@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;
+}
有关注册自定义程序属性的更多信息,请参阅添加自定义程序属性文档 。
Variant stacking order
在 v3 中,堆叠变体是从右到左应用的,但在 v4 中,我们更新了它们,使其从左到右应用,看起来更像 CSS 语法。
要针对此更改更新项目,请反转项目中任何顺序敏感的堆叠变体的顺序:
-<ul class="py-4 first:*:pt-0 last:*:pb-0">
+<ul class="py-4 *:first:pt-0 *:last:pb-0">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
如果有的话,你可能只有很少的这些——直接子变体 (*
) 和任何排版插件变体( prose-headings
)是你可能最有可能使用的,即使这样,也只有在你将它们与其他变体堆叠在一起时。
任意值的变量
在 v3 中,您可以不使用 var()
将 CSS 变量用作任意值,但最近对 CSS 的更新意味着这通常是模棱两可的,因此我们在 v4 中更改了语法,以使用括号而不是方括号。
要针对此更改更新项目,请将旧的变量速记语法替换为新的变量速记语法:
-<div class="bg-[--brand-color]"></div>
+<div class="bg-(--brand-color)"></div>
Hover styles on mobile
在 v4 中,我们更新了 hover
变体,仅在主输入设备支持 hover 时适用:
@media (hover: hover) {
.hover\:underline:hover {
text-decoration: underline;
}
}
如果您以依赖于触摸设备触发点击悬停的方式构建网站,这可能会产生问题。如果这对您来说是一个问题,您可以使用自己的使用旧实现的变体覆盖 hover
变体:
@custom-variant hover (&:hover);
不过,一般来说,我们建议将悬停功能视为一种增强功能,而不是依赖它来使您的网站正常工作,因为触摸设备并不真正具有悬停功能。
Transitioning outline-color
transition
和 transition-color
程序属性现在包括 outline-color
属性。
这意味着,如果您添加的轮廓具有焦点上的自定义颜色,您将看到从默认颜色开始的颜色过渡。为避免这种情况,请确保无条件地设置轮廓颜色,或者为两种状态显式设置它:
-<button class="transition hover:outline-2 hover:outline-cyan-500"></button>
+<button class="outline-cyan-500 transition hover:outline-2"></button>
Disabling core plugins
在 v3 中,有一个 corePlugins
选项,你可以用它来完全禁用框架中的某些工具。v4 中不再支持此功能。
Using the theme() function
由于 v4 包含所有主题值的 CSS 变量,因此我们建议尽可能使用这些变量而不是 theme()
函数:
.my-class {
- background-color: theme(colors.red.500);
+ background-color: var(--color-red-500);
}
对于您仍然需要使用 theme()
函数的情况(例如在不支持 CSS 变量的媒体查询中),您应该使用 CSS 变量名称而不是旧的点表示法:
-@media (width >= theme(screens.xl)) {
+@media (width >= theme(--breakpoint-xl)) {
/* ... */
}
Using a JavaScript config file
JavaScript 配置文件仍受支持以实现向后兼容性,但在 v4 中不再自动检测到它们。
如果您仍然需要使用 JavaScript 配置文件,则可以使用 @config
指令显式加载它:
@config "../../tailwind.config.js";
基于 JavaScript 的配置中的 corePlugins
、safelist
和 separator
选项在 v4.0 中不受支持。要在 v4 中将程序属性列入安全列表,请使用 @source inline。
Theme values in JavaScript
在 v3 中,我们导出了一个 resolveConfig
函数,您可以使用该函数将基于 JavaScript 的配置转换为可在其他 JavaScript 中使用的平面对象。
我们在 v4 中删除了这一点,希望人们可以使用我们直接生成的 CSS 变量,这要简单得多,并且会显着减少您的捆绑包大小。
例如,流行的 React Motion 库允许你对 CSS 变量值进行动画处理:
<motion.div animate={{ backgroundColor: 'var(--color-blue-500)' }} />
如果需要访问 JS 中解析的 CSS 变量值,可以使用 getComputedStyle
获取文档根上主题变量的值:
let styles = getComputedStyle(document.documentElement)
let shadow = styles.getPropertyValue('--shadow-xl')
Using @apply with Vue, Svelte, or CSS modules
在 v4 中,与主 CSS 文件(e.g. CSS 模块文件、Vue、Svelte 或 Astro 中的 <style>
块等)分开捆绑的样式表无权访问其他文件中定义的主题变量、自定义程序属性和自定义变体。
要使这些定义在这些上下文中可用,请使用 @reference导入它们,而无需在捆绑包中复制任何 CSS:
<template>
<h1>Hello world!</h1>
</template>
<style>
+ @reference "../../app.css";
h1 {
@apply text-2xl font-bold text-red-500;
}
</style>
或者,您可以直接使用 CSS 主题变量,而不是完全使用 @apply
,这也将提高性能,因为 Tailwind 不需要处理这些样式:
<template>
<h1>Hello world!</h1>
</template>
<style>
h1 {
+ color: var(--text-red-500);
}
</style>
您可以找到有关将 Tailwind 与 CSS 模块结合使用的更多文档。
Using Sass, Less, and Stylus
Tailwind CSS v4.0 不是为与 Sass、Less 或 Stylus 等 CSS 预处理器一起使用而设计的。将 Tailwind CSS 本身视为您的预处理器 — 您不应该将 Tailwind 与 Sass 一起使用,原因与不将 Sass 与 Stylus 一起使用的原因相同。因此,不能将 Sass、Less 或 Stylus 用于样式表,也不能在 Vue、Svelte、Astro 等中使用 <style>
块。
在兼容性文档中了解更多信息。