入門(Getting Started)
將你的 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,你可以使用我們的升級工具來為你完成絕大部分的繁重工作:
$ npx @tailwindcss/upgrade對於大多數專案,升級工具會自動化整個遷移過程,包括更新你的相依套件、將設定檔遷移到 CSS,以及處理範本檔案的任何變更。
升級工具需要 Node.js 20 或更高版本,因此在執行之前請確保你的環境已更新。
我們建議在新分支中執行升級工具,然後仔細檢視差異並在瀏覽器中測試你的專案,以確保所有變更都正確。在複雜的專案中,你可能需要手動調整一些東西,但無論如何,這個工具都會為你節省大量時間。
瀏覽所有 v4 中的破壞性變更並充分了解發生了什麼變化也是一個好主意,以防有其他升級工具沒有捕捉到的需要在專案中更新的內容。
在 v3 中,tailwindcss 套件是一個 PostCSS 插件,但在 v4 中,PostCSS 插件位於專用的 @tailwindcss/postcss 套件中。
此外,在 v4 中,匯入和供應商前綴現在會自動為你處理,因此如果你的專案中有 postcss-import 和 autoprefixer,可以移除它們:
export default { plugins: { "postcss-import": {}, tailwindcss: {}, autoprefixer: {}, "@tailwindcss/postcss": {}, },};如果你正在使用 Vite,我們建議從 PostCSS 插件遷移到我們新的專用 Vite 插件,以獲得更好的效能和最佳的開發體驗:
import { defineConfig } from "vite";import tailwindcss from "@tailwindcss/vite";export default defineConfig({ plugins: [ tailwindcss(), ],});在 v4 中,Tailwind CLI 位於專用的 @tailwindcss/cli 套件中。更新你的任何建構命令以使用新套件:
npx tailwindcss -i input.css -o output.cssnpx @tailwindcss/cli -i input.css -o output.css以下是 Tailwind CSS v4.0 中所有破壞性變更的完整清單。
我們的升級工具會自動為你處理大部分這些變更,因此如果可以的話,我們強烈建議使用它。
Tailwind CSS v4.0 專為現代瀏覽器設計,目標是 Safari 16.4、Chrome 111 和 Firefox 128。我們依賴現代 CSS 功能如 @property 和 color-mix() 來實現核心框架功能,Tailwind CSS v4.0 在舊版瀏覽器中無法運作。
如果你需要支援舊版瀏覽器,我們建議目前繼續使用 v3.4。我們正在積極探索相容模式,以幫助人們更快升級,希望未來能分享更多相關消息。
在 v4 中,你使用常規的 CSS @import 語句匯入 Tailwind,而不是使用你在 v3 中使用的 @tailwind 指令:
@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-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 |
我們重新命名了預設的陰影、圓角和模糊比例,以確保每個通用類別都有一個命名值。「裸」版本仍然為了向後相容而可用,但 <utility>-sm 通用類別除非更新為各自的 <utility>-xs 版本,否則看起來會不同。
要為這些變更更新你的專案,請將所有 v3 通用類別替換為它們的 v4 版本:
<input class="shadow-sm" /><input class="shadow-xs" /><input class="shadow" /><input class="shadow-sm" />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" />在 v3 中,ring 通用類別新增了一個 3px 的環。我們在 v4 中將其改為 1px,以使其與 border 和 outline 保持一致。
要為此變更更新你的專案,請將任何 ring 的使用替換為 ring-3:
<input class="ring ring-blue-500" /><input class="ring-3 ring-blue-500" />我們變更了 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>我們變更了 divide-x-* 和 divide-y-* 通用類別使用的選擇器,以解決大型頁面上的嚴重效能問題:
/* Before */.divide-y-4 > :not([hidden]) ~ :not([hidden]) { border-top-width: 4px;}/* Now */.divide-y-4 > :not(:last-child) { border-bottom-width: 4px;}如果你曾經將這些通用類別與行內元素一起使用、曾經為子元素新增其他邊距/內距來調整它們的間距,或調整特定子元素的邊框,你可能會在專案中看到變化。
在 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>在 v3 中,container 通用類別有幾個設定選項如 center 和 padding,這些在 v4 中已不存在。
要在 v4 中自訂 container 通用類別,請使用 @utility 指令擴展它:
@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 的行為:
@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 顏色的地方新增 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 的慣用用法。
我們在 v4 中對 Preflight 的基礎樣式進行了一些小變更:
在 v3 中,佔位符文字預設使用你設定的 gray-400 顏色。我們在 v4 中將其簡化為使用當前文字顏色的 50% 不透明度。
你可能甚至不會注意到這個變更(它甚至可能讓你的專案看起來更好),但如果你想保留 v3 的行為,請將此 CSS 新增到你的專案:
@layer base { input::placeholder, textarea::placeholder { color: var(--color-gray-400); }}按鈕現在使用 cursor: default 而不是 cursor: pointer,以符合預設的瀏覽器行為。
如果你想繼續預設使用 cursor: pointer,請將這些基礎樣式新增到你的 CSS:
@layer base { button:not(:disabled), [role="button"]:not(:disabled) { cursor: pointer; }}Preflight 現在會重設 <dialog> 元素的邊距,以與其他元素的重設方式保持一致。
如果你仍希望對話框預設置中,請將此 CSS 新增到你的專案:
@layer base { dialog { margin: auto; }}像 block 或 flex 這樣的顯示類別不再優先於元素上的 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); /* ... */}在 v3 中,你可以透過在通用類別名稱的開頭(但在任何變體之後)放置 ! 來將通用類別標記為 important。在 v4 中,你應該將 ! 放在類別名稱的最末端:
<div class="flex! bg-red-500! hover:bg-red-600/50!"> <!-- ... --></div>舊的方式仍然為了相容性而支援,但已被棄用。
在 v3 中,你在 @layer utilities 或 @layer components 中定義的任何自訂類別都會被 Tailwind 視為真正的通用類別,並自動與 hover、focus 或 lg 等變體一起使用,差別在於 @layer components 會始終在產生的樣式表中排在前面。
在 v4 中,我們使用原生階層級聯,不再劫持 @layer at-rule,因此我們引入了 @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;}在新增自訂通用類別文件中了解更多關於註冊自訂通用類別的資訊。
在 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>在任意值中,grid-cols-*、grid-rows-* 和 object-* 通用類別中的逗號之前會被替換為空格。這種特殊行為存在於 Tailwind CSS v3 中是為了與 v2 相容。這種相容性在 v4.0 中已不存在,必須使用底線來表示空格。
要為此變更更新你的專案,請將原本要用作空格的逗號替換為底線:
<div class="grid-cols-[max-content,auto]"></div><div class="grid-cols-[max-content_auto]"></div>在 v4 中,我們更新了 hover 變體,使其僅在主要輸入裝置支援 hover 時才套用:
@media (hover: hover) { .hover\:underline:hover { text-decoration: underline; }}如果你建構的網站依賴觸控裝置在點擊時觸發 hover,這可能會造成問題。如果這對你來說是個問題,你可以使用你自己的變體覆寫 hover 變體,使用舊的實作:
@custom-variant hover (&:hover);但一般來說,我們建議將 hover 功能視為增強功能,而不是依賴它來讓你的網站運作,因為觸控裝置並不真正具有 hover 的能力。
transition 和 transition-colors 通用類別現在包含 outline-color 屬性。
這意味著如果你在 focus 時新增了自訂顏色的輪廓,你會看到顏色從預設顏色過渡。為避免這種情況,請確保你無條件設定輪廓顏色,或明確為兩種狀態設定它:
<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 中的個別 rotate、scale 和 translate 屬性。通常這不應該影響行為,但有幾種情況需要注意:
你之前可以透過 transform-none 「重設」你的 rotate、scale 和 translate 通用類別。這不再有效,你需要改為重設個別屬性:
<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]。
<button class="transition-[opacity,transform] hover:scale-150"></button><button class="transition-[opacity,scale] hover:scale-150"></button>在 v3 中,有一個 corePlugins 選項可用於完全停用框架中的某些通用類別。這在 v4 中不再支援。
由於 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)) { /* ... */}JavaScript 設定檔仍然為了向後相容而支援,但在 v4 中不再自動偵測。
如果你仍需要使用 JavaScript 設定檔,可以使用 @config 指令明確載入它:
@config "../../tailwind.config.js";v4.0 不支援基於 JavaScript 設定中的 corePlugins、safelist 和 separator 選項。若要在 v4 中使用安全清單通用類別,請使用 @source inline()。
在 v3 中,我們匯出了一個 resolveConfig 函式,你可以用它將基於 JavaScript 的設定轉換為扁平物件,以便在其他 JavaScript 中使用。
我們在 v4 中移除了這個功能,希望人們可以直接使用我們產生的 CSS 變數,這更簡單且會顯著減少你的打包大小。
例如,流行的 React 函式庫 Motion 讓你可以動畫到 CSS 變數值和從 CSS 變數值動畫:
<motion.div animate={{ backgroundColor: "var(--color-blue-500)" }} />如果你需要在 JS 中存取已解析的 CSS 變數值,可以使用 getComputedStyle 取得文件根元素上的主題變數值:
let styles = getComputedStyle(document.documentElement);let shadow = styles.getPropertyValue("--shadow-xl");在 v4 中,與主 CSS 檔案分開打包的樣式表(例如 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 模組中找到更多文件。
Tailwind CSS v4.0 並非設計用於與 Sass、Less 或 Stylus 等 CSS 預處理器一起使用。把 Tailwind CSS 本身當作你的預處理器——你不應該將 Tailwind 與 Sass 一起使用,就像你不會將 Sass 與 Stylus 一起使用一樣。因此,無法在 Vue、Svelte、Astro 等的樣式表或 <style> 區塊中使用 Sass、Less 或 Stylus。
在相容性文件中了解更多。