Tailwind CSS v4 に移行したらクラスが効かなくなった
Tailwind CSS v4 は v3 から大きくアーキテクチャが変わったため、移行時に「クラスを書いてもスタイルが全く当たらない」「ビルドエラーが出る」「カスタムカラーだけ反映されない」といった問題が多発しています。
この記事では、v4 移行時によくハマる5つの原因と対処法を解説します。
こんな症状が出ていませんか?
bg-blue-500を書いても背景色が変わらない- ビルドは成功するが CSS ファイルがほぼ空になる
- カスタムカラーやフォントサイズが反映されない
devコンソールにCannot apply unknown utility classが出る- 特定のクラスだけ当たらない(shadow, blur, rounded など)
原因1: @tailwind ディレクティブの書き方が変わった
v3 では CSS ファイルに以下の3行を書く必要がありました。
/* v3 の書き方 */
@tailwind base;
@tailwind components;
@tailwind utilities;
v4 ではこれが廃止され、1行のインポートに変わりました。
/* v4 の書き方 */
@import "tailwindcss";
v3 の書き方のまま v4 パッケージをインストールすると、@tailwind ディレクティブが認識されず、スタイルが全く生成されません。CSS ファイルのエントリーポイント(main.css や globals.css など)を確認して書き換えてください。
原因2: PostCSS プラグインのパッケージ名が変わった
v3 では PostCSS の設定に tailwindcss パッケージを直接指定していました。
// v3: postcss.config.js
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
v4 では @tailwindcss/postcss という別パッケージになりました。まずインストールします。
npm install -D @tailwindcss/postcss
// v4: postcss.config.js
export default {
plugins: {
'@tailwindcss/postcss': {},
},
}
autoprefixer は v4 に内蔵されたため、別途の指定は不要です(残しても動きますが不要です)。
Vite を使っている場合は PostCSS ではなく専用の Vite プラグインを使う方法が推奨されています。
npm install -D @tailwindcss/vite
// vite.config.ts
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [
tailwindcss(),
],
})
Vite プラグインを使う場合は postcss.config.js の Tailwind 設定は不要です。
原因3: tailwind.config.js が v4 では自動読み込みされない
v4 では設定が CSS ファーストの @theme ディレクティブに移行しました。v3 で使っていた tailwind.config.js は v4 では自動的に読み込まれないため、カスタムカラーやフォントが一切反映されなくなります。
// v3: tailwind.config.js(v4 では無視される)
/** @type {import('tailwindcss').Config} */
export default {
theme: {
extend: {
colors: {
brand: '#3B82F6',
accent: '#F59E0B',
},
fontFamily: {
sans: ['Noto Sans JP', 'sans-serif'],
},
},
},
}
v4 では、カスタムテーマの設定は CSS ファイル内の @theme ブロックで行います。
/* v4: main.css */
@import "tailwindcss";
@theme {
--color-brand: #3B82F6;
--color-accent: #F59E0B;
--font-family-sans: "Noto Sans JP", sans-serif;
--spacing-128: 32rem;
}
これにより bg-brand、text-accent、font-sans、p-128 などのクラスが使えるようになります。変数名の命名規則は --{カテゴリ}-{名前} の形式です。
原因4: content 設定が廃止されたが自動検出が効いていない
v3 では content にスキャン対象のファイルパスを明示的に指定する必要がありました。
v4 では content 設定が廃止され、自動検出に変わりました。 .gitignore の内容を参照して自動的にスキャン対象を判定します。
ただし、以下のケースでは自動検出がうまく動かないことがあります。
.gitignoreが存在しない、または不完全- モノレポ構成でサブパッケージの
.gitignoreがない - 別パッケージ(UI ライブラリなど)に定義されたクラスを使っている
bg-${color}-500のような動的クラス名を使っている
この場合は @source ディレクティブで明示的にスキャン対象を追加できます。
@import "tailwindcss";
/* 外部パッケージのソースを追加スキャン */
@source "../node_modules/@myorg/ui/src";
/* テンプレートファイルを追加 */
@source "./src/templates/**/*.html";
動的に生成するクラス名は @source inline で直接ホワイトリスト登録できます。
/* 動的クラス名の登録 */
@source inline("bg-red-500 bg-blue-500 bg-green-500 bg-yellow-500");
原因5: v4 でクラス名が変更・削除されたものがある
v4 では一部のユーティリティクラスが名前変更または削除されています。v3 のクラス名をそのまま書いていると、クラスが存在しないためスタイルが当たりません。
特によく引っかかる変更点は shadow・blur・rounded 系のデフォルト値シフトです。
| v3 のクラス名 | v4 のクラス名 |
|---|---|
shadow-sm |
shadow-xs |
shadow(デフォルト) |
shadow-sm |
shadow-md |
shadow-md(変更なし) |
blur-sm |
blur-xs |
blur(デフォルト) |
blur-sm |
rounded-sm |
rounded-xs |
rounded(デフォルト) |
rounded-sm |
透明度の指定方法も変わっています。
<!-- v3: bg-opacity-* 修飾子 -->
<div class="bg-blue-500 bg-opacity-50">...</div>
<!-- v4: スラッシュ記法(bg-opacity-* は削除) -->
<div class="bg-blue-500/50">...</div>
text-opacity-*、border-opacity-*、ring-opacity-* なども同様に削除されています。全てスラッシュ記法に統一してください。
公式アップグレード CLI を使う
手動移行が大変な場合は、公式のアップグレード CLI を試すと多くの変更を自動修正できます。
npx @tailwindcss/upgrade
このツールが自動変換する主な内容:
tailwind.config.js→ CSS の@themeブロック@tailwindディレクティブ →@import "tailwindcss"- 削除・変更されたクラス名のリネーム
- PostCSS 設定ファイルの更新
全ての変更を自動変換できるわけではないため、実行後は必ず動作確認を行ってください。特に動的クラス名や外部パッケージ参照は手動で対応が必要です。
まとめ
| 症状 | 原因 | 対処法 |
|---|---|---|
| CSS が全く生成されない | @tailwind ディレクティブが旧形式 |
@import "tailwindcss" に変更 |
| ビルドエラー / スタイルが出ない | PostCSS 設定が旧パッケージ | @tailwindcss/postcss に変更 |
| カスタムカラーが当たらない | tailwind.config.js が無視される |
CSS の @theme ブロックに移行 |
| 特定クラスだけ当たらない(外部ライブラリ等) | 自動検出が効かない | @source で明示指定 |
| shadow / blur 等が変 | v4 でクラス名が変更された | 変更後のクラス名に修正 |
v4 は CSS ファーストの設計に大きく舵を切り、v3 との互換性が低い部分があります。まずは npx @tailwindcss/upgrade を試し、それでも解決しない場合は上記の5つの原因を順番にチェックしてみてください。
