言語を切り替える
テーマを切り替える

Next.js + Tailwind CSS ベストプラクティス:設定からダークモードまでの完全ガイド(2025年版)

VS Code でボタンコンポーネントの className を見てみてください——23 個。bg-blue-500 から dark:hover:bg-blue-800 まで、1 行にぎっしり詰まって横スクロールバーがずいぶん伸びています。同僚がデスクの横を通り、画面をちらっと見て言いました。「これ、何書いてるの?」

その瞬間、何と答えればいいかわかりませんでした。Tailwind はもう近 2 年使っていて、確かに速い。でもコードはだんだん暗号のようになっていく。コピペは気持ちいい、直すときは地獄——すべてのボタンに同じ角丸を当てたいだけなのに、ファイルごとに rounded-lg を検索して一つずつ直す。

この苦しみを味わっているのは私だけではありません。2025 年、Tailwind CSS は v4 に、Next.js は 15 に。設定の仕方、ダークモード、パフォーマンス最適化がすべて変わりました。最初は私も戸惑いました。設定ファイルがない? darkMode: 'class' はどこへ? いろいろ踏んだあと、ようやくコツがつかめました。

この記事では、その間の実践で得たことをまとめます。公式ドキュメントの写し取りではなく、プロジェクトで試して効いた方法です。クラス名を爆発させない、ダークモードをきれいに入れる、CSS バンドルを 500KB から 50KB に落とす。Tailwind のクラスに苦しめられた人、v4 へ上げるか迷っている人は、ぜひ読み進めてください。

2025 年の変化:Tailwind CSS v4 + Next.js 15

まず v4 の最大の変化——設定ファイルがなくなったこと。

そう、おなじみの tailwind.config.js は v4 ではオプションです。最初見たときはネタだと思いました。Next.js 15.3 の新規プロジェクトを開くと、本当にありません。Tailwind チームは「ゼロコンフィグ」と呼びます。プロジェクトファイルを自動スキャンし、そのまま使える。

カスタムができないわけではありません。むしろ v4 では、カスタムの置き場所がより直感的になりました——global.css です。テーマ色、スペーシング、フォントはすべて CSS 変数で定義します。

@theme {
  --color-primary: #3b82f6;
  --color-secondary: #8b5cf6;
  --font-sans: 'Inter', sans-serif;
}

最初は戸惑いました。「後退じゃないの?」と。2 日使うと、変更のほうが速い。以前はテーマ色を変えるたびに dev サーバーを再起動してコンパイル待ち。今は CSS 変数を変えれば HMR が即反映。デザイナーも CSS 変数は読めるので、「blue-500 がどの青か」と聞かれなくなりました。

もう一つは速度。v4 は Rust で書き直され、公式では約 5 倍。私の環境ではコールドスタートが 8 秒から 2 秒未満。ベンチマーク遊びではありません——1 日に dev サーバーを十何回起動するなら、積み重なってコーヒーが一杯分増えます。

500KB→50KB
CSS バンドル最適化
約 90% 削減、500KB から 50KB へ
5倍
ビルド速度
v4 は Rust 製、約 5 倍高速
8秒→2秒
コールドスタート
8 秒から 2 秒未満へ

Next.js 15 側では、App Router が標準です。Tailwind と組み合わせると、Server Components のスタイル分離もよく、スタイル汚染を気にしなくて済みます。注意点は、Client Components には 'use client' を付けること。付けないとダークモード切り替えが壊れます(後述)。

もう一つ、見落とされがちな変更:border-color のデフォルトが currentColor になりました。色を指定しない枠線は文字色に追従します。v3 から上げると、枠線が「消えた」ように見えることがあります——実際は文字と同じ色になっているだけです。私も一度ハマり、半日かけて原因を特定しました。

まとめると、v4 の変更は大きいが方向は正しい。より速く、よりシンプルで、直感に合う。最初の慣れの期間を越えると、戻れなくなる人が多いです。

クラス名が長すぎる問題:コンポーネント化の正しいやり方

冒頭の話に戻ります。23 個クラスのボタンはどうするか。

多くの人の第一反応は @apply です。Tailwind クラスを CSS に押し込み、.btn-primary のような名前にすると見た目はすっきり。私もそうしていました。Tailwind 作者の Adam Wathan が Twitter で言っていたのを思い出します。「@apply を大量に使っているなら、Tailwind の設計思想を誤解しているかもしれない。」

きつい言葉ですが、筋は通っています。@apply はユーティリティを事前に CSS に焼き込むので、オンデマンド生成の利点が薄れます。「カプセル化している」つもりが、手動で CSS を膨らませている——あるプロジェクトでは @apply を多用し、本番 CSS が 30KB から 120KB に跳ね上がりました。

正しいのは コンポーネントでのカプセル化 です。

よく使うスタイルの組み合わせを React コンポーネントにまとめ、クラスは一度だけ書きます。

// ❌ 以前:どこでも同じ長い className
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-lg shadow-md transition duration-200">
  送信
</button>

// ✅ 今:コンポーネントにまとめる
<Button variant="primary">送信</Button>

Button 内ではクラスはそのまま長くても、呼び出し側はすっきり。ボタン全体のスタイルを変えるときも、1 ファイルを直せば済みます。

これだけでは足りません。primary / secondary / danger など、状態ごとに別コンポーネントは現実的ではありません。ここで cva(class-variance-authority)が活きます。

バリアント管理専用のライブラリで、Tailwind と相性がよいです。

import { cva, type VariantProps } from 'class-variance-authority'

const buttonStyles = cva(
  // ベーススタイル
  'font-bold rounded-lg transition duration-200',
  {
    variants: {
      variant: {
        primary: 'bg-blue-500 hover:bg-blue-700 text-white',
        secondary: 'bg-gray-200 hover:bg-gray-300 text-gray-800',
        danger: 'bg-red-500 hover:bg-red-700 text-white'
      },
      size: {
        sm: 'py-1 px-3 text-sm',
        md: 'py-2 px-4',
        lg: 'py-3 px-6 text-lg'
      }
    },
    defaultVariants: {
      variant: 'primary',
      size: 'md'
    }
  }
)

export function Button({
  variant,
  size,
  children,
  ...props
}: VariantProps<typeof buttonStyles> & React.ButtonHTMLAttributes<HTMLButtonElement>) {
  return (
    <button className={buttonStyles({ variant, size })} {...props}>
      {children}
    </button>
  )
}

使う側はこうなります。

<Button variant="primary">保存</Button>
<Button variant="danger" size="lg">削除</Button>
<Button variant="secondary" size="sm">キャンセル</Button>

TypeScript がバリアント名もチェックしてくれます。shadcn/ui もこのパターンで、コードが読みやすい理由のひとつです。

@apply が完全 NG というわけではありません。サードパーティのスタイルを上書きするときなど、コンポーネント化できない場面では @apply でも問題ありません。自前の UI はできるだけコンポーネント化し、手を抜かないこと。

カスタムテーマ:デザインシステムを作る

コンポーネントをまとめたら、次はプロジェクト全体の見た目をどう揃えるか。

以前のプロジェクトでは、青が 5〜6 種類:blue-400blue-500#3B82F6rgb(59, 130, 246)……デザイナーは首を振ります。「どの規格?」その後、色・フォント・スペーシングを固定した デザインシステム が必要だとわかりました。

v4 ではこれが特に楽です。先ほどの @theme に書きます。

/* app/globals.css */
@import 'tailwindcss';

@theme {
  /* ブランドカラー */
  --color-brand-primary: #3b82f6;
  --color-brand-secondary: #8b5cf6;

  /* セマンティックカラー */
  --color-success: #10b981;
  --color-warning: #f59e0b;
  --color-error: #ef4444;

  /* ニュートラル(明→暗) */
  --color-neutral-50: #f9fafb;
  --color-neutral-100: #f3f4f6;
  --color-neutral-500: #6b7280;
  --color-neutral-900: #111827;

  /* フォントファミリー */
  --font-sans: 'Inter', system-ui, sans-serif;
  --font-mono: 'Fira Code', monospace;

  /* スペーシング(8px グリッド) */
  --spacing-unit: 0.5rem; /* 8px */

  /* 角丸 */
  --radius-sm: 0.25rem;
  --radius-md: 0.5rem;
  --radius-lg: 1rem;
}

定義したら、そのまま Tailwind クラスで使えます。

<div className="bg-brand-primary text-neutral-50 rounded-md">
  ブランドカラー背景
</div>

bg-blue-500 ではなく bg-brand-primary にしている点が重要です。ブランド色を変えるときは変数 1 つでサイト全体に反映。blue-500 を grep して百箇所直す必要はありません。

v3 方式の tailwind.config.ts も残せます。

import type { Config } from 'tailwindcss'

export default {
  content: [
    './app/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx,mdx}',
  ],
  theme: {
    extend: {
      // デフォルトテーマを拡張(推奨)
      colors: {
        brand: {
          primary: '#3b82f6',
          secondary: '#8b5cf6',
        },
      },
      fontFamily: {
        sans: ['Inter', 'sans-serif'],
      },
    },
  },
} satisfies Config

extend が肝です。theme.colors を直接書くと Tailwind のデフォルト色を上書きし、bg-red-500 などが使えなくなります。extend は追加であり、置き換えではありません。

CSS 変数と Tailwind 設定を組み合わせると、実行時のテーマ切り替えもできます。

:root {
  --color-primary: #3b82f6;
}

[data-theme='purple'] {
  --color-primary: #8b5cf6;
}
// tailwind.config.ts
colors: {
  primary: 'var(--color-primary)',
}

テーマ切り替えで CSS を再コンパイルせず、DOM 属性を変えるだけ。SaaS でユーザーがテーマ色を選ぶ UI に向いています。

デザインシステムができれば、チームも楽です。新人は globals.css を見れば使う色がわかる。「この青は適当」が減ります。

ダークモード:チラつきのない実装

ダークモードで一番大きく転んだのは、最初の実装です。

v3 のチュートリアルどおりにトグルを作り、クリックすると一瞬白く光ってから黒くなる。ユーザーから「目がやられた」と言われました。いわゆる FOUC(Flash of Unstyled Content)で、Next.js の SSR が原因でした。

v4 ではダークモードの設定も変わります。v3 の darkMode: 'class' は不要。デフォルトで class 戦略です。チラつきは残るので、next-themes が定番です。

npm install next-themes

ルートレイアウトで ThemeProvider で包みます。

// app/layout.tsx
import { ThemeProvider } from 'next-themes'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="zh-CN" suppressHydrationWarning>
      <body>
        <ThemeProvider attribute="class" defaultTheme="system" enableSystem>
          {children}
        </ThemeProvider>
      </body>
    </html>
  )
}

suppressHydrationWarning は忘れずに。next-themes はクライアントで <html>class="dark" を付け、SSR 結果と食い違うため React が警告します。この属性で抑えられます。

トグルは Client Component に書きます。

'use client'

import { useTheme } from 'next-themes'
import { useEffect, useState } from 'react'

export function ThemeToggle() {
  const [mounted, setMounted] = useState(false)
  const { theme, setTheme } = useTheme()

  useEffect(() => setMounted(true), [])

  if (!mounted) return null // SSR 不一致を避ける

  return (
    <button
      onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
      className="rounded-lg p-2 hover:bg-neutral-100 dark:hover:bg-neutral-800"
    >
      {theme === 'dark' ? '🌞' : '🌙'}
    </button>
  )
}

CSS 変数もダーク向けに用意します。

@theme {
  --color-bg-primary: #ffffff;
  --color-text-primary: #111827;
}

.dark {
  --color-bg-primary: #111827;
  --color-text-primary: #f9fafb;
}

または Tailwind の dark: プレフィックスを直接使います。

<div className="bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-50">
  ダークモード対応
</div>

色設計の話:ダークモードは白黒反転だけでは足りません。真っ黒 #000000 は眩しいので #111827#1a1a1a の深いグレー。文字も真っ白より #f9fafb が読みやすい。シャドウはダークでは効きにくいので、層を ring で表現する例もあります。

// ライトモード:下方向のシャドウ
<div className="shadow-lg dark:shadow-none dark:ring-1 dark:ring-neutral-800">

ダークでは ring(枠線)のほうが立体感が出ます。

画像はダークで明るすぎることがあるので、明度を少し落とすフィルタも有効です。

.dark img {
  filter: brightness(0.9);
}

こうした細部まで揃えて、初めて「使える」ダークモードになります。

パフォーマンス:CSS を小さく速く

冒頭の 500KB→50KB は誇張ではなく、実際にやった数字です。

v4 は JIT がデフォルトでオンデマンド生成です。それでも content の書き方次第で差が出ます。

よくあるのはスキャン範囲が広すぎる書き方です。

// ❌ スキャン範囲が広すぎる
content: [
  './**/*.{js,ts,jsx,tsx}',
]

node_modules.next まで拾い、無駄な時間がかかります。必要なディレクトリに絞ります。

// ✅ 必要なディレクトリだけスキャン
content: [
  './app/**/*.{js,ts,jsx,tsx,mdx}',
  './components/**/*.{js,ts,jsx,tsx}',
  './lib/**/*.{js,ts}',
]

私の環境では、これだけで dev サーバー起動が約 40% 速くなりました。

動的クラス名も要注意です。

// ❌ purge 対象から漏れる
const colors = ['red', 'blue', 'green']
<div className={`bg-${colors[0]}-500`}>

Tailwind は完全な bg-red-500 を静的に読めず、本番ビルドで落ちます。完全なクラス名を書くか、

// ✅ 完全なクラス名を書く
const colorMap = {
  red: 'bg-red-500',
  blue: 'bg-blue-500',
  green: 'bg-green-500',
}
<div className={colorMap[color]}>

どうしても動的なら safelist で残します。

// tailwind.config.ts
safelist: [
  {
    pattern: /bg-(red|blue|green)-500/,
  },
]

safelist は増やしすぎると CSS が再び太ります。可能なら完全なクラス名、やむを得ないときだけ safelist です。

v4 は本番で CSS 圧縮も標準。さらに詰めるなら cssnano を PostCSS に足せます。

// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    ...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {}),
  },
}

見落としがちなのが bundle 監視です。@next/bundle-analyzer で定期確認しています。

npm install --save-dev @next/bundle-analyzer
// next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
})

module.exports = withBundleAnalyzer({
  // その他の設定
})

ANALYZE=true npm run build で可視化レポートが出て、どのパッケージが太いか一目です。

Netflix の Top 10 ページは CSS が 6.5KB という話もあります。極限まで削った例ですが、「本当に使うスタイルだけ」という考え方は参考になります。

コードレビューで、同僚が @heroicons/react を丸ごと import しているのを見つけ、2 アイコンだけの import に変えたら 200KB 減ったこともあります。小さな積み重ねです。

パフォーマンスは一度きりではなく習慣です。リリース前に bundle 分析を回し、CSS が肥大化するのを防ぎましょう。

v3 から v4 へ:スムーズな移行

まだ v3 なら、今上げるべきかはプロジェクト次第です。

新規は v4 で問題ないことが多いです。既存は変更コストを見積もってください。v4 には破壊的変更があり、npm install だけでは済みません。

最大は設定の置き場所です。v3 の tailwind.config.js の内容は global.css へ移します。

/* 旧 tailwind.config.js */
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: '#3b82f6',
      },
    },
  },
}

/* 新 globals.css */
@theme {
  --color-primary: #3b82f6;
}

カスタムユーティリティも @layer utilities から @utility へ。

/* v3 */
@layer utilities {
  .text-balance {
    text-wrap: balance;
  }
}

/* v4 */
@utility text-balance {
  text-wrap: balance;
}

もう一つの罠:コンポーネントクラスにバリアントが効かなくなったこと。v3 では次のような書き方がありました。

/* v3 では可 */
@layer components {
  .btn {
    @apply px-4 py-2 rounded;
  }
}

/* hover:btn や dark:btn のようなバリアントも使えた */

v4 では hover:btn はエラーになります。utility にするか React コンポーネントに寄せてください。

枠線色の罠も再掲です。border だけだと文字色に追従するので、グレーを明示します。

// v3:枠線は自動でグレー
<div className="border"></div>

// v4:枠線は文字色に追従、明示指定が必要
<div className="border border-neutral-300"></div>

段階的移行の目安です。

  1. ステップ 1:v4 を入れ、dev で明らかな崩れがないか確認
  2. ステップ 2@layer を検索し、@utility または @theme に置き換え
  3. ステップ 3border を検索し、色未指定に border-neutral-300 などを追加
  4. ステップ 4:theme 設定を CSS へ移し、都度テスト
  5. ステップ 5:purge で落ちた動的クラスは safelist で救済

規模次第で半日〜1 日。一気にやらず、バッチごとにロールバックしやすくするのが安全です。

shadcn/ui などのライブラリは v4 対応状況を先に確認してください。私はライブラリより先に v4 に上げ、コンポーネントのスタイルが大量に崩れた経験があります。

v4 は良い進化ですが、必須ではありません。v3 で安定しているなら、タイミングを選んでよいです。

まとめ

23 個クラスのボタンから <Button variant="primary"> へ——この道のりは近 2 年です。

Tailwind と Next.js の組み合わせは強いですが、そのままでは伸びしろが残ります。v4 の変更は大きく見えますが、設定の簡素化、速度、開発体験の方向は正しいと感じています。

コンポーネント化、テーマ、ダークモード、パフォーマンス——全部を一度に入れる必要はありません。今の痛みに効くものから試してください。プロジェクト全体を一度にリファクタするのは疲れるし、リスクも高いです。

私のおすすめはコンポーネント化から。午後いっぱいで Button、Card、Input を cva 付きで作る。リスクが小さく、効果はすぐ見えます。そのあとダークモードやテーマです。

v4 へ上げるかは急がなくてよいです。エコシステム、使っている UI ライブラリ、工数があるかを見てください。新しさより、合っているかが大事です。

Tailwind で同じ悩みをした人、もっと良いやり方があればコメントで教えてください。私よりエレガントな方法があるかもしれません。

記事内のコード例は GitHub にも置いています(文末リンク)。そのまま使えます。問題は Issues で。

読むだけでなく、手を動かしてみてください。動かさないコードは身につきません。

Next.js + Tailwind CSS v4 完全セットアップ手順

ゼロ設定からコンポーネント化、パフォーマンス最適化、ダークモードまでの一連のステップ

⏱️ 目安時間: 3 時間

  1. 1

    ステップ1: Tailwind v4 の基本設定

    v4 の変化:
    • 設定ファイルは不要(ゼロコンフィグ)
    • カスタムは global.css の CSS 変数へ
    • Rust 製エンジンで約 5 倍高速

    global.css の設定例:
    ```css
    @theme {
    --color-primary: #3b82f6;
    --color-secondary: #8b5cf6;
    --font-sans: 'Inter', sans-serif;
    }
    ```

    メリット:
    • CSS 変数を変えると HMR が即反映
    • デザイナーも読みやすい
    • dev サーバーの再起動が不要

    ポイント:v4 は「ゼロコンフィグ」。プロジェクトファイルを自動スキャンしてそのまま使える。
  2. 2

    ステップ2: クラス名爆発への対処

    課題:1 行に 23 個のクラスが並ぶ。

    解決:コンポーネント化

    cva でバリアント管理:
    ```tsx
    import { cva, type VariantProps } from 'class-variance-authority'
    import { cn } from '@/lib/utils'

    const buttonVariants = cva(
    'inline-flex items-center justify-center rounded-md',
    {
    variants: {
    variant: {
    default: 'bg-primary text-primary-foreground',
    destructive: 'bg-destructive text-destructive-foreground',
    },
    size: {
    default: 'h-10 px-4 py-2',
    sm: 'h-9 px-3',
    lg: 'h-11 px-8',
    },
    },
    }
    )

    export function Button({ variant, size, className, ...props }) {
    return (
    <button
    className={cn(buttonVariants({ variant, size }), className)}
    {...props}
    />
    )
    }
    ```

    効果:23 個 → variant / size / className の 3 つ程度へ

    ポイント:午後いっぱいで Button、Card、Input を cva 付きで作る。
  3. 3

    ステップ3: パフォーマンス最適化(500KB→50KB)

    手法:

    1. content / purge 設定:
    ```js
    // tailwind.config.js(v3)
    module.exports = {
    content: ['./app/**/*.{js,ts,jsx,tsx}'],
    // 実際に使うクラスだけ残す
    }
    ```

    2. 必要分だけインポート:
    ```tsx
    // ライブラリ丸ごと import しない
    import { Button } from '@/components/ui/button'
    ```

    3. 動的クラス名を避ける:
    ```tsx
    // ❌ 動的だと purge されやすい
    const color = `bg-${theme}-500`

    // ✅ 完全なクラス名
    const color = theme === 'blue' ? 'bg-blue-500' : 'bg-red-500'
    ```

    4. JIT(v3):
    ```js
    module.exports = {
    mode: 'jit', // オンデマンド生成
    }
    ```

    効果:500KB → 50KB(約 90% 削減)
  4. 4

    ステップ4: ダークモード設定

    v4 では darkMode 設定不要。next-themes を使う:

    インストール:
    ```bash
    npm install next-themes
    ```

    ThemeProvider:
    ```tsx
    'use client'
    import { ThemeProvider } from 'next-themes'

    export function Providers({ children }) {
    return (
    <ThemeProvider attribute="class" defaultTheme="system">
    {children}
    </ThemeProvider>
    )
    }
    ```

    dark: プレフィックス:
    ```tsx
    <div className="bg-white dark:bg-gray-900 text-black dark:text-white">
    コンテンツ
    </div>
    ```

    ポイント:
    • v4 は dark: を標準サポート
    • next-themes でテーマ管理
    • darkMode 設定は不要

FAQ

Tailwind v4 にはどんな変化がある?
主な変化:

1. 設定ファイルはオプション(ゼロコンフィグ)
• tailwind.config.js は必須ではない
• プロジェクトファイルを自動スキャン

2. カスタムは global.css へ
• CSS 変数でテーマ色・スペーシング・フォントを定義
• 変数変更は HMR で即反映

3. Rust 製エンジン
• 約 5 倍高速
• コールドスタート 8 秒→2 秒未満

4. ダークモードの簡素化
• darkMode 設定不要
• dark: プレフィックスを標準サポート

メリット:設定が簡単、速度向上、HMR が速い

注意:v4 はベータ期間があるため、本番は安定版を待つ選択もあり。
クラス名が長すぎる問題はどう解決する?
課題:1 行に 23 個のクラス。

解決:コンポーネント化 + cva

```tsx
import { cva } from 'class-variance-authority'

const buttonVariants = cva(
'inline-flex items-center justify-center',
{
variants: {
variant: {
default: 'bg-primary',
destructive: 'bg-destructive',
},
size: {
default: 'h-10 px-4',
sm: 'h-9 px-3',
},
},
}
)

export function Button({ variant, size, className, ...props }) {
return (
<button
className={cn(buttonVariants({ variant, size }), className)}
{...props}
/>
)
}
```

効果:
• 23 個 → 3 個程度
• バリアントを一元管理
• 変更が 1 箇所で済む

おすすめ:午後いっぱいで Button、Card、Input を cva 付きで作る。
Tailwind のパフォーマンスをどう最適化する(500KB→50KB)?
手法:

1. content / purge:
```js
module.exports = {
content: ['./app/**/*.{js,ts,jsx,tsx}'],
}
```

2. 必要分だけインポート:
```tsx
import { Button } from '@/components/ui/button'
```

3. 動的クラス名を避ける:
```tsx
// ❌
const color = `bg-${theme}-500`

// ✅
const color = theme === 'blue' ? 'bg-blue-500' : 'bg-red-500'
```

4. JIT(v3):
```js
module.exports = {
mode: 'jit',
}
```

効果:500KB → 50KB(約 90%)

ポイント:実際に使うクラスだけ残し、動的クラス名は避ける。
Tailwind v4 のダークモードはどう設定する?
v4 では darkMode 設定不要。next-themes を使う:

インストール:
```bash
npm install next-themes
```

設定:
```tsx
'use client'
import { ThemeProvider } from 'next-themes'

export function Providers({ children }) {
return (
<ThemeProvider attribute="class" defaultTheme="system">
{children}
</ThemeProvider>
)
}
```

使用:
```tsx
<div className="bg-white dark:bg-gray-900">
コンテンツ
</div>
```

ポイント:
• v4 は dark: を標準サポート
• next-themes でテーマ管理
• darkMode 設定は不要

注意:<html> に suppressHydrationWarning を付ける。
Tailwind v4 にアップグレードすべき?
検討材料:

メリット:
• 約 5 倍高速
• 設定が簡単
• HMR が速い

デメリット:
• ベータ期間がある
• エコシステムが追いついていない場合がある
• 移行に工数がかかる

おすすめ:
• 新規:v4 を試す価値あり
• 既存:安定版を待つ選択もあり
• 迷ったら:v3 のまま、v4 安定を待つ

ポイント:新しさより合っているか。ライブラリ対応と工数を確認する。
Tailwind のテーマはどう管理する?
v4 では CSS 変数で管理:

global.css:
```css
@theme {
--color-primary: #3b82f6;
--color-secondary: #8b5cf6;
--font-sans: 'Inter', sans-serif;
}
```

使用:
```tsx
<div className="bg-primary text-primary-foreground">
コンテンツ
</div>
```

メリット:
• 変数変更で HMR 即反映
• デザイナーにも読みやすい
• dev サーバー再起動不要

おすすめ:
• まずコンポーネント化
• Button、Card、Input を cva 付きで作る
• その後テーマを整える

4分で読めます · 公開日: 2025年12月20日 · 更新日: 2026年6月8日

関連記事

コメント

GitHubアカウントでログインしてコメントできます