tailwind-v4 について
Tailwind CSS v4 に沿った記述と、旧式の v3 パターン回避を支援する実践ガイドです。CSS ファースト設定、ユーティリティの変更、バリアント、モーションを扱い、固定バージョンでの確認も促します。
主な機能
- 01CSS ファースト設定のガイド
- 02v3 から v4 へのユーティリティと構文の変更
- 03任意値より生成済みユーティリティを優先
- 04カスタム CSS や JavaScript に代わるバリアント活用
- 05v4 の挙動変更とモーションの指針
活用シーン
- 01新しい Tailwind CSS v4 スタイルの記述
- 02v3 時代の構文を使うコードの更新
- 03プロジェクトの固定バージョンに沿ったユーティリティ確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mastra-ai/ mastra --skill tailwind-v4インストール後、Claude Code で/tailwind-v4を入力して読み込まれたか確認します。
詳細
Tailwind CSS v4
慣用的な Tailwind v4 の記述方法と、新しいコードでは使うべきではないものの、引き続きコンパイルされる v3 時代の構文の見分け方です。
バージョンと参照先
新しいユーティリティを使う前に、固定されているバージョンを確認してください。playground のパッケージでは、package.json で tailwindcss のバージョンが固定されています(執筆時点では 4.3.3。scrollbar-*、zoom-*、tab-* などの v4 ユーティリティを含みます)。ユーティリティ、バリアント、ディレクティブが固定バージョンに存在するか不明な場合は、推測せずドキュメントで確認してください。
- ユーティリティ/バリアントのリファレンス:https://tailwindcss.com/docs
- v3 から v4 への移行:https://tailwindcss.com/docs/upgrade-guide
- 各マイナーバージョンで追加された機能:https://tailwindcss.com/blog/tailwindcss-v4(および
/tailwindcss-v4-1、/tailwindcss-v4-3、...)
CSS ファーストの設定
Tailwind v4 の設定は JavaScript ではなく、CSS で行います。
| 使用するもの | 使用しないもの(v3 時代) |
|---|---|
@import 'tailwindcss' | @tailwind base/components/utilities |
ユーティリティを生成するトークンには @theme { --color-x: ...; } | 新しい作業での tailwind.config.ts |
カスタムユーティリティには @utility name { ... }(バリアントに対応) | @layer utilities { .name { ... } } |
@custom-variant dark (&:is(.dark *)) | JS の plugins/addVariant |
追加のソース/セーフリストには @source "path"/@source inline("...") | content 配列/safelist 設定 |
カスタム CSS 内で Tailwind のバリアントを適用するには @variant dark { ... } | メディアクエリ/セレクターの重複 |
スコープ付きスタイル(Vue、CSS Modules)での @apply には @reference "app.css" | スタイルシートのインポートの重複 |
CSS では var(--color-x)、JS では getComputedStyle | theme() 関数、resolveConfig |
既存の JS 設定との連携に限り @config "…"/@plugin "…" | 新しい JS 設定やプラグインの追加 |
@theme 変数は API です。それぞれがネイティブ CSS 変数を出力し、ユーティリティも生成します(--color-* → bg-*/text-*/border-*/...、--text-* → text-*、--shadow-* → shadow-*、--animate-* → animate-*、--breakpoint-* → レスポンシブバリアント)。通常の :root { --x: ...; } 変数は何も生成しません。実行時専用の値にはこちらを使用してください。トークンの値が別の変数を参照する場合(--color-x: var(--y))、ユーティリティが宣言箇所で参照を解決できるよう、@theme inline で宣言してください。カスタム CSS では、--alpha(var(--color-x) / 50%) と --spacing(4) が v3 の theme() による計算に代わります。
v3 → v4 の名称変更
単独の名前はスケール上で1段階小さい値へ移動したため、v3の表記を使うと、気づかないうちにサイズや濃さが小さくなります。
| v3 | v4 |
|---|---|
shadow-sm / shadow | shadow-xs / shadow-sm |
drop-shadow-sm / drop-shadow | drop-shadow-xs / drop-shadow-sm |
blur-sm / blur | blur-xs / blur-sm |
rounded-sm / rounded | rounded-xs / rounded-sm |
outline-none | outline-hidden(アクセシビリティに安全);outline-noneは実際にアウトラインを削除するようになりました |
ring(3px) | ring-3;デフォルトのリングは1pxのcurrentColorになりました |
bg-opacity-50、text-opacity-* | 不透明度修飾子:bg-black/50、text-white/50 |
bg-gradient-to-r | bg-linear-to-r(さらに新しいbg-conic-*、bg-radial-*) |
!bg-red-500(接頭辞) | bg-red-500!(接尾辞) |
flex-shrink-* / flex-grow-* | shrink-* / grow-* |
bg-[--var] | bg-(--var);括弧を使う場合はbg-[var(--var)]が必要になりました |
grid-cols-[a,b](カンマ) | アンダースコア:grid-cols-[max-content_auto] |
任意の値より生成済みユーティリティを優先する
スペーシングスケールは無限で、どの数値もcalc(var(--spacing) * n)を通じてコンパイルされるため、v3時代の任意の値の多くには名前付きの形式があります。
| 使用しない | 使用する |
|---|---|
min-w-[400px]、w-[600px] | min-w-100、w-150 |
h-[1.5rem] w-[1.5rem] | size-6 |
mt-[68px] | mt-17 |
grid-cols-[repeat(15,minmax(0,1fr))] | grid-cols-15 |
h-[100dvh]、w-[100dvw]、h-[1lh] | h-dvh、w-dvw、h-lh |
max-w-[80rem] | max-w-7xl(コンテナスケール) |
data-[current]:opacity-100 | data-current:opacity-100(値には引き続き角括弧を使用します:data-[state=open]:) |
bg-[var(--row-bg)] | bg-(--row-bg);曖昧な場合は型ヒントを使用します:text-(color:--fg)、text-(length:--size) |
max-h-[calc(100dvh-3rem)]、grid-cols-[200px_minmax(0,1fr)]、[mask-type:luminance]のような任意のプロパティなど、固有の値には角括弧が引き続き適切です。
クラス文字列は完全な形で、静的に検出可能でなければなりません。プロパティは完全な文字列に対応付けてください({ success: 'bg-positive1' }[tone])。`bg-${tone}-500`のように断片を組み立てないでください。
バリアントで対応できるものに、CSS や JS を手書きしないでください
スタイルシートのルール、style プロパティ、またはスタイル設定用のイベントハンドラーを書く前に、バリアントで対応できないか確認してください。
| 手書きの実装 | Tailwind |
|---|---|
CSS の .btn:active { ... } | active:bg-surface5 |
:focus-visible のルール | focus-visible:outline-accent1 |
[aria-expanded="true"] セレクター | aria-expanded:rotate-180(任意の aria-* ブール値または値) |
[data-state="open"] セレクター | data-[state=open]:opacity-100、ブール値の場合:data-current: |
| 兄弟要素/子要素のスタイル設定用 JS ホバー/フォーカス状態 | group/group-hover:、peer/peer-checked:、in-focus: |
| 親要素の状態セレクター/JS の「子要素があるか」チェック | has-checked:bg-accent1、has-[>svg]:pl-8 |
CSS の mask-image/フェードアウトのグラデーション | mask-b-from-80%、mask-t-from-* |
@media (hover: none) ブロック | pointer-coarse:/pointer-fine: |
| CSS の first/last/nth ルール | first:、last:、odd:、nth-3:、not-first: |
| CSS ですべての子要素にスタイルを設定する | *:rounded-full(子要素)、**:data-avatar:rounded-full(子孫要素) |
新機能 — 回避策や JS より先に活用してください
field-sizing-content— JS のリサイズリスナーを使わずに、テキストエリアを自動的に拡大します。wrap-anywhere/wrap-break-word—min-w-0の回避策を使わずに、フレックス内の長い単語を折り返します。items-center-safe、justify-center-safe— はみ出す場合はstartにフォールバックする中央揃えです。pointer-coarse:/pointer-fine:— ユーザーエージェントの判定をせずに、タッチ対象を調整できます。user-valid:/user-invalid:— ユーザー操作後にのみ検証スタイルを適用します(:validとは異なります)。starting:(display/ポップオーバーにはtransition-discreteを併用)— JS でマウントを工夫せずに、入場時のトランジションを適用します。text-shadow-*、mask-t-from-*/mask-b-to-*(フェードアウトするエッジ)、scheme-dark(ネイティブのコントロール/スクロールバー)、3D 変形(rotate-x-*、perspective-*)。
覚えておくべき動作の変更点
- 変形には個別の CSS プロパティが使われます。カスタムのトランジションリストには
transition-[opacity,transform]ではなくtransition-[opacity,scale]を指定し、scale-none/rotate-none/translate-noneでリセットします。 hover:はホバーに対応したデバイスにのみ適用されます(@media (hover: hover))。タッチで必要な機能をホバーに依存させないでください。border-*、divide-*、リング、アウトラインのデフォルト色はcurrentColorです。色が重要な場合は明示的に指定してください。- バリアントの重ね合わせは左から右に適用されます。v3 の
first:*:pt-0は、現在は*:first:pt-0です。 space-x/y-*のセレクターが変更されました(:not(:last-child))。代わりに、gap-*を使うフレックスまたはグリッドを優先してください。- コンテナークエリーは組み込みです。親要素には
@container、子要素には@sm:/@max-md:を指定します。 - v4 の便利なバリアント:
starting:(入場時のトランジション)、not-*、in-*(groupクラスを使わずにgroup-*のように動作)、nth-*、*:(直接の子要素)、**:(子孫要素)、inert:。
モーション
- 装飾的なアニメーションには条件を付けてください:
motion-safe:animate-spin motion-reduce:animate-none。 - 再利用可能なアニメーションは
@theme内に@keyframesを含む--animate-*トークンとして定義します。ローカルで一度だけ使う場合はanimate-(--local-animation)またはanimate-[...]を使います。