
Tailwind CSS v4 実践移行 - JS設定から CSS-first と @theme へどう移すか
Tailwind CSS v4 は、見た目には「また新バージョン」ですが、中身は設定の思想そのものが変わったメジャーです。これまで tailwind.config.js(JavaScript)に書いていた設定が、CSS ファイル側に寄る(CSS-first)。ここを理解せずにアップグレードすると「設定がどこにいったのか分からない」状態になります。
この記事では、v4 への移行を移行設計の勘所として整理します。基本的な使い方は Tailwind CLI ガイドに譲り、ここでは「v3 から何が変わり、どう移すか」に絞ります。
NOTE
このブログ自身も Tailwind CSS v4 で構築しています。v4 は @property や color-mix() といったモダン CSS に依存するため、ブラウザ要件が上がります(後述)。古いブラウザを公式サポートするプロダクトは、移行前に要件を確認してください。
まずは自動アップグレードツール
手作業で全部やる必要はありません。公式のアップグレードツールが、依存の更新・設定の CSS 移行・テンプレートの書き換えの大半を自動化します。
npx @tailwindcss/upgradeWARNING
アップグレードツールは必ず新しいブランチで実行し、差分をレビューしてください。後述のユーティリティ改名(shadow 系・ring 系など)やクラス内の ! の位置変更まで自動で書き換わるため、変更量が大きくなります。ビルド後はブラウザでの目視確認も必須です。
何が根本的に変わったか
1. @tailwind ディレクティブが @import に
v3 で3行書いていた読み込みが、v4 では1行になります。
@tailwind base;
@tailwind components;
@tailwind utilities;@import "tailwindcss";2. 設定は tailwind.config.js から @theme へ(CSS-first の核心)
v4 最大の転換がこれです。デザイントークン(色・フォント・ブレークポイント等)を、JavaScript の設定オブジェクトではなく、CSS の @theme ディレクティブに CSS 変数として定義します。
@import "tailwindcss";
@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);
}ここで定義した変数は、そのまま bg-avocado-100 や font-display、3xl: ブレークポイントとして使えます。しかも CSS 変数なので、var(--color-avocado-100) として素の CSS からも参照できます。oklch() のような新しい色空間が標準で使えるのも v4 ならではで、CSS 2026 のブラウザネイティブ機能とも地続きです。
NOTE
tailwind.config.js(JS 設定)は v4 で自動検出されなくなりました。既存の JS 設定を引き続き使いたい場合は、CSS 側で @config "../../tailwind.config.js"; と明示的に読み込みます。ただし corePlugins・safelist・separator といった一部オプションは v4.0 では非対応です。
3. パッケージが用途ごとに分離
v3 では tailwindcss 一つで PostCSS プラグインも CLI も兼ねていましたが、v4 では役割ごとにパッケージが分かれました。
| 用途 | v3 | v4 |
|---|---|---|
| PostCSS プラグイン | tailwindcss | @tailwindcss/postcss |
| CLI | 内蔵 | @tailwindcss/cli |
| Vite プラグイン | PostCSS 経由 | @tailwindcss/vite(専用) |
Vite を使うなら、専用プラグインを使うのが推奨です。Vite 7 と Rolldownの構成ともよく噛み合います。
import { defineConfig } from "vite";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
plugins: [tailwindcss()],
});CLI でビルドする場合は専用パッケージで実行します。
npx @tailwindcss/cli -i input.css -o output.css詰まりやすい差分
ブラウザ要件が上がる
v4 はモダン CSS(@property・color-mix() など)に依存するため、対応ブラウザの下限が上がります。
| ブラウザ | 必要バージョン |
|---|---|
| Safari | 16.4 以上 |
| Chrome | 111 以上 |
| Firefox | 128 以上 |
これより古いブラウザを公式サポートする必要があるなら、無理に上げず v3.4 系に留まるのも正しい判断です。
ユーティリティの改名(自動だが把握しておく)
アップグレードツールが書き換えてくれますが、レビューのために主な改名を把握しておきます。スケールの一貫性を整える方向の変更です。
shadow-smがshadow-xsに、shadowがshadow-smに(1段ずれる)rounded-smがrounded-xsに、blur-smがblur-xsにringのデフォルト幅が 3px から 1px に変更。従来の 3px が必要ならring-3を使うoutline-noneはoutline-hiddenに- 透明度ユーティリティ
bg-opacity-50等は廃止。スラッシュ記法bg-black/50に flex-shrink-*がshrink-*、flex-grow-*がgrow-*、overflow-ellipsisがtext-ellipsisに
!important の位置が末尾に
v3 では先頭に付けていた ! が、v4 ではクラス名の末尾に移動します。
<!-- v3 -->
<div class="!flex !bg-red-500">
<!-- v4 -->
<div class="flex! bg-red-500! hover:bg-red-600/50!">カスタムユーティリティは @utility で
@layer utilities で書いていた独自ユーティリティは、専用の @utility ディレクティブに変わります。
/* v3 */
@layer utilities {
.tab-4 { tab-size: 4; }
}
/* v4 */
@utility tab-4 {
tab-size: 4;
}Vue / Svelte / CSS Modules の別ファイル
v4 では、コンポーネントの <style> ブロックや CSS Modules など別スタイルシートからはテーマ変数に自動アクセスできません。@reference で参照を宣言するか、CSS 変数を直接使います(後者のほうが高速)。
@reference "../../app.css";
h1 { @apply text-2xl font-bold text-red-500; }移行手順まとめ
詰まりどころを踏まえた安全な順序です。
- Node を確認: 20 以上に
- 新ブランチでアップグレードツール:
npx @tailwindcss/upgradeを実行し、差分をレビュー - 設定の移行を確認:
tailwind.config.jsが@themeに移ったか、JS 設定を残すなら@configで読み込んでいるか - ビルド連携を更新: Vite なら
@tailwindcss/vite、PostCSS なら@tailwindcss/postcss、CLI なら@tailwindcss/cli - ブラウザ要件を確認: 古い対応が必要なら v3.4 据え置きも検討
- 目視確認: ユーティリティ改名・
!の位置・別ファイルの@referenceを中心にブラウザで確認
まとめ
- v4 の本質は「JS 設定から CSS-first へ」の転換。トークンは
@themeに CSS 変数として書く - 移行は
npx @tailwindcss/upgrade(Node 20+)で大半を自動化。必ず新ブランチで差分レビュー @tailwind3行は@import "tailwindcss"1行に。tailwind.config.jsは自動検出されず、使うなら@config- パッケージは用途別に分離(
@tailwindcss/postcss//cli//vite) - ブラウザ要件が上がる(Safari 16.4+ / Chrome 111+ / Firefox 128+)。古い対応が要るなら v3.4 据え置きも選択肢
- 改名・
!の位置・@utility・@referenceが詰まりやすい。ツール任せにせずレビューする
v4 は派手な新ユーティリティより「設定の置き場所が変わった」ことが本丸です。@theme と CSS 変数の発想に慣れれば、Tailwind とプレーンな CSS の境目がなめらかになり、デザイントークンの扱いがぐっと素直になります。