2025年1月23日、Tailwind 4.0がリリースされました。
既存プロジェクトで3.xを使っていた私は、Next.js 14から15への移行と一緒にTailwind CSSも更新することにしました。
Next.jsを15へ上げる前に、まずTailwindを更新してテストすることをおすすめします。
今回は公式ドキュメントに基づき、
Tailwind CSS 3.0から4.0への移行
を整理します。
4.0への移行は、性能と生産性の面で大きな利点があります。
Tailwind CSS v4.0は最新ブラウザー向けに設計され、Safari 16.4、Chrome 111、Firefox 128をサポートします。それ以前のブラウザーにはv3.4を使います。
Tailwindチームは、更新を簡単にする
@tailwindcss/upgradeを提供しています。
実行前に未コミットの変更を確認し、
git stashか
git commitで安全に保存してください。
次の作業を自動で行います。
- Tailwind CSSの更新
- tailwind.config.jsの削除または変換
- postcss.config.jsの変換
- テンプレート内のクラスの整理
- 必要に応じたtheme API中心の設定への変更
upgrade tool
が更新してくれても、新しい使い方と変更点を理解する必要があります。
4.0の変更を順に整理します。
従来はCSSの@tailwindから読み込んでいましたが、v4では削除されました。
代わりにCSSから直接Tailwindをインポートします。
/* v3 */
/* @tailwind base; */
/* @tailwind components; */
/* @tailwind utilities; */
/* v4 */
@import "tailwindcss";
@tailwindは不要なので、CSSから削除します。
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の縮小 |
|---|
| flex-grow-* | grow-* | Flexの拡張 |
|---|
| overflow-ellipsis | text-ellipsis | はみ出しの省略 |
|---|
| decoration-slice | box-decoration-slice | ボックス装飾の分割 |
|---|
| decoration-clone | box-decoration-clone | ボックス装飾の複製 |
|---|
v4では次の名前が変わりました。
この変更はTailwind CSS v4.0に適用されます。
shadow、drop-shadow、blur、backdrop-blur、rounded、outline、ringの変更です。
| 以前 | 以後 | 機能 |
|---|
| 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、blur、roundedのスケールが変更されました。
互換性のため旧名も動作しますが、-smを-xsへ変えないと見た目が異なります。
{/* v3 버전 */}
<input class="shadow-sm" />
{/* v4 버전 */}
<input class="shadow-xs" />
{/* v3 버전 */}
<input class="shadow" />
{/* v4 버전 */}
<input class="shadow-sm" />
outlineは既定で
outline-width: 1pxと
outline-style: solidを含みます。
以前の
outlineには
outline-style: solidだけが含まれていました。
現在の
outlineには
outline-width: 1pxと
outline-style: solidの両方があります。
{/* v3 버전 */}
<input class="outline outline-2" />
{/* v4 버전 */}
<input class="outline-2" />
また、outline-noneは実際にはoutline-style: noneを適用しないため、outline-hiddenへ改名されました。
{/* v3 버전 */}
<input class="focus:outline-none" />
{/* v4 버전 */}
<input class="focus:outline-hidden" />
ringの太さが3pxから1pxへ変わりました。
{/* v3 버전 */}
<input class="ring ring-blue-500" />
{/* v4 버전 */}
<input class="ring-3 ring-blue-500" />
ダークモードでも
to-*が維持され、不要なら
via-noneで取り除きます。
変更後:
<div class="bg-gradient-to-r from-red-500 via-orange-400 to-yellow-400 dark:via-none dark:from-blue-500 dark:to-teal-400"></div>
containerのcenterやpaddingなどは削除されたため、直接定義します。
@utility container {
margin-inline: auto;
padding-inline: 2rem;
}
border-*と
divide-*の既定色は
currentColorになりました。
gray-200を維持したければ、次のように設定します。
@layer base {
*, ::after, ::before, ::backdrop, ::file-selector-button {
border-color: var(--color-gray-200, currentColor);
}
}
既定色は、文字色の50%の透明度になりました。
以前の見た目を保つには、次を追加します。
@layer base {
input::placeholder,
textarea::placeholder {
color: var(--color-gray-400);
}
}
ボタンのカーソルが
pointerから
defaultに変わりました。
以前のスタイルを保つには、次を追加します。
@layer base {
button:not(:disabled),
[role="button"]:not(:disabled) {
cursor: pointer;
}
}
@layer base {
dialog {
margin: auto;
}
}
@layer utilitiesの代わりに@utilityを使います。
@utility tab-4 {
tab-size: 4;
}
{/* v3 버전 */}
<ul class="py-4 first:*:pt-0 last:*:pb-0">
{/* v4 버전 */}
<ul class="py-4 *:first:pt-0 *:last:pb-0">
bg-[--color]からbg-(--color)へ変わりました。
<div class="bg-(--brand-color)"></div>
タッチ端末に対応するため、独自variantを登録できます。
@custom-variant hover (&:hover);
outline-colorもtransitionに含まれる 🔗
<button class="transition hover:outline-2 hover:outline-cyan-500"></button>
corePluginsでユーティリティーを無効にする方法は、サポートされません。
.my-class {
background-color: var(--color-red-500);
}
4-18. JavaScript設定は明示的に読み込む 🔗
@config "../../tailwind.config.js";
4-19. JavaScriptからthemeの値へアクセスする 🔗
resolveConfigなしでも、getComputedStyleで値を取得できます。
let styles = getComputedStyle(document.documentElement);
let shadow = styles.getPropertyValue("--shadow-xl");
@import 'tailwindcss';
@theme {
--color-primary: #1da1f2;
--font-sans: 'Inter', sans-serif;
}
@utilities {
.btn {
@apply px-4 py-2 rounded bg-primary text-white;
}
}
// Before (3.x)
theme: {
extend: {
colors: {
brand: '#3490dc',
},
},
}
// After (4.x)
@theme {
--color-brand: #3490dc;
}
{/* Before (3.x) */}
<div class="text-slate-900/80"></div>
{/* After (4.x) */}
<div class="text-slate-900 text-opacity-80"></div>
- すべてのテンプレートパスでスタイルが動くか確認する。
npm run buildでエラーや警告がないか確認する。
- PostCSSの設定が反映されているか確認する。
- 開発・本番の両方で動作を確認する。
Tailwind CSS 4.0は単なる更新ではなく、設定構造、対応環境、利用方法にわたる
根本的な再設計
です。
自動ツールを使うか、上のガイドで一つずつ確認すれば、安全かつ素早く移行できます。
CSS中心の設定や最新ブラウザーへの対応は、今後のウェブ開発でも大きな利点になるでしょう。
最新版を導入する方の道しるべになれば幸いです。