mcpField
T
tailwind-theme-builder

tailwind-theme-builder

github.com/jezwebデザイン・UI1.1k3.2k 回インストール3 週間前に更新
リポジトリ

tailwind-theme-builder について

CSS 変数とダークモードを使い、Tailwind v4 と shadcn/ui のテーマを設定するスキルです。設定用ファイルや ThemeProvider、よくある設定不具合の対処法を提供します。

主な機能

  1. 01Vite プラグインによる Tailwind v4 の設定
  2. 02@theme inline による CSS 変数のマッピング
  3. 03ThemeProvider を使ったダークモード設定
  4. 04セマンティックなカラートークンの適用
  5. 05テーマ設定で起きやすい問題の診断

活用シーン

  1. 01テーマ対応の shadcn/ui プロジェクトを初期化
  2. 02ライト、ダーク、システムの各モードを追加
  3. 03ユーティリティクラスの欠落や色切り替え不具合を修正

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jezweb/claude-skills --skill tailwind-theme-builder

インストール後、Claude Code で/tailwind-theme-builderを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
components.json
index.css
theme-provider.tsx
tsconfig.app.json
utils.ts
vite.config.ts
references/
migration-guide.md

詳細

Tailwind テーマビルダー

ダークモードを備えた、完全にテーマ設定された Tailwind v4 + shadcn/ui プロジェクトをセットアップします。設定済みの CSS、テーマプロバイダー、動作するコンポーネントライブラリを生成します。

アーキテクチャ:4 ステップのパターン

Tailwind v4 では、CSS 変数ベースのテーマ設定に特定のアーキテクチャが必要です。このパターンは必須です。手順を省略または変更すると、テーマが正しく機能しません。

仕組み
CSS Variable Definition --> @theme inline Mapping --> Tailwind Utility Class
--background           --> --color-background     --> bg-background
(with hsl() wrapper)      (references variable)     (generated class)

ダークモードの切り替え:

ThemeProvider toggles .dark class on <html>
  --> CSS variables update automatically (.dark overrides :root)
  --> Tailwind utilities reference updated variables
  --> UI updates without re-render
ベストプラクティス
  • セマンティックな名前: --blue-500 ではなく --primary を使用します
  • 前景色との組み合わせ: すべての背景色に前景色が必要です(--primary + --primary-foreground)
  • WCAG コントラスト: 通常のテキストは 4.5:1、大きなテキストは 3:1、UI コンポーネントは 3:1
  • チャートの色: @theme inline マッピングを使って個別の変数を使用し、スタイルプロパティでは var(--chart-1) を参照します

ワークフロー

ステップ 1:依存関係をインストールする
pnpm add tailwindcss @tailwindcss/vite
pnpm add -D @types/node tw-animate-css
pnpm dlx shadcn@latest init

# Delete v3 config if it exists
rm -f tailwind.config.ts
ステップ 2:Vite を設定する

assets/vite.config.ts をコピーするか、Tailwind プラグインを追加します。

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
import path from 'path'

export default defineConfig({
  plugins: [react(), tailwindcss()],
  resolve: { alias: { '@': path.resolve(__dirname, './src') } }
})
ステップ 3:4 ステップの CSS アーキテクチャ(必須)

この正確な順序が必要です。手順を省略すると、テーマが正しく機能しません。

src/index.css:

@import "tailwindcss";
@import "tw-animate-css";

/* 1. Define CSS variables at root (NOT inside @layer base) */
:root {
  --background: hsl(0 0% 100%);
  --foreground: hsl(222.2 84% 4.9%);
  --primary: hsl(221.2 83.2% 53.3%);
  --primary-foreground: hsl(210 40% 98%);
  /* ... all semantic tokens */
}

.dark {
  --background: hsl(222.2 84% 4.9%);
  --foreground: hsl(210 40% 98%);
  --primary: hsl(217.2 91.2% 59.8%);
  --primary-foreground: hsl(222.2 47.4% 11.2%);
}

/* 2. Map variables to Tailwind utilities */
@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
}

/* 3. Apply base styles (NO hsl() wrapper here) */
@layer base {
  body {
    background-color: var(--background);
    color: var(--foreground);
  }
}

結果: bg-background、text-primary などが自動的に機能します。ダークモードは .dark クラスで切り替わります。セマンティックカラーには dark: バリアントは不要です。

ステップ 4:ダークモードをセットアップする

assets/theme-provider.tsx をコンポーネントディレクトリにコピーし、アプリをラップします。

import { ThemeProvider } from '@/components/theme-provider'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
    <App />
  </ThemeProvider>
)

テーマ切り替えを追加するには、ドロップダウンメニューをインストールしてから、以下の ModeToggle コンポーネントを使用します。

pnpm dlx shadcn@latest add dropdown-menu
// src/components/mode-toggle.tsx
import { Moon, Sun } from "lucide-react"
import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { useTheme } from "@/components/theme-provider"

export function ModeToggle() {
  const { setTheme } = useTheme()

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="outline" size="icon">
          <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
          <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
          <span className="sr-only">Toggle theme</span>
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuItem onClick={() => setTheme("light")}>Light</DropdownMenuItem>
        <DropdownMenuItem onClick={() => setTheme("dark")}>Dark</DropdownMenuItem>
        <DropdownMenuItem onClick={() => setTheme("system")}>System</DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}
ステップ 5:components.json を設定する
{
  "tailwind": {
    "config": "",
    "css": "src/index.css",
    "baseColor": "slate",
    "cssVariables": true
  }
}

"config": "" は重要です。v4 は tailwind.config.ts を使用しません。


重要なルール

必ず行うこと:

  • :root/.dark 内の色を hsl() で囲みます
  • すべての CSS 変数のマッピングに @theme inline を使用します
  • @tailwindcss/vite プラグインを使用します(PostCSS は使用しません)
  • tailwind.config.ts が存在する場合は削除します

行わないこと:

  • :root/.dark を @layer base 内に配置する
  • .dark { @theme { } } を使用する(v4 はネストされた @theme をサポートしていません)
  • 二重に囲む:hsl(var(--background))
  • @layer base クラスに @apply を使用する(代わりに @utility を使用します)

18 の注意点すべて

すばやく原因を特定
#症状原因解決策
1変数が無視される/テーマが壊れる@layer base 内の :root:root と .dark をルートレベルに移動する
2ダークモードの色が切り替わらない.dark { @theme { } }CSS 変数と単一の @theme inline を使用する
3すべての色が黒または白になるhsl() の二重ラップhsl(var(...)) ではなく var(--background) を使用する
4bg-primary が生成されないtailwind.config.ts に色を設定している設定ファイルを削除し、@theme inline を使用する
5bg-background クラスがない@theme inline ブロックがない変数をマッピングする @theme inline を追加する
6shadcn コンポーネントが壊れるcomponents.json に設定パスがある"config": ""(空文字列)を設定する
7Tailwind が処理されないPostCSS プラグインを使用している@tailwindcss/vite プラグインに切り替える
8@/ インポートが失敗するパスエイリアスがないtsconfig.app.json に paths を追加する
9dark: バリアントが冗長dark:bg-primary-dark を使用しているbg-primary だけを使用する。変数で処理されます
10あちこちで色がハードコードされているbg-blue-600 dark:bg-blue-400 を使用しているbg-primary などのセマンティックトークンを使用する
11クラスのマージで不具合が起きるクラスを文字列連結している@/lib/utils の cn() を使用する
12Radix Select がクラッシュする値が空文字列 value=""value="placeholder" を使用する
13Tailwind のバージョンが間違っているtailwindcss@^3 をインストールしているtailwindcss@^4.1.0 と @tailwindcss/vite をインストールする
14ピア依存関係が不足しているtailwindcss だけをインストールしているclsx、tailwind-merge、@types/node もインストールする
15ダークモードで壊れるライトモードだけをテストしているライト、ダーク、システム、および切り替え時の遷移をテストする
16WCAG のコントラスト比を満たさない見た目には問題がない比率を確認する:通常のテキストは 4.5:1、大きな文字/UI は 3:1
17アニメーションのインポートでビルドに失敗するtailwindcss-animate(非推奨)を使用しているtw-animate-css またはネイティブ CSS アニメーションを使用する
18CSS の優先順位に問題があるshadcn の初期化後に重複した @layer base がある単一の @layer base ブロックにまとめる
コード例で見る注意点

#1 -- @layer base 内の :root

Tailwind v4 は @theme/@layer の外側にある CSS を削除しますが、:root は設定を保持するためにルートレベルに置く必要があります。これはセットアップで最もよくある失敗です。

誤り:

@layer base {
  :root { --background: hsl(0 0% 100%); }
}

正しい例:

:root { --background: hsl(0 0% 100%); }
@layer base {
  body { background-color: var(--background); }
}

#2 -- ネストされた @theme

Tailwind v4 はセレクター内の @theme をサポートしていません。:root/.dark の CSS 変数と、単一の @theme inline ブロックを使用してください。

誤り:

@theme { --color-primary: hsl(0 0% 0%); }
.dark { @theme { --color-primary: hsl(0 0% 100%); } }

正しい例:

:root { --primary: hsl(0 0% 0%); }
.dark { --primary: hsl(0 0% 100%); }
@theme inline { --color-primary: var(--primary); }

#3 -- hsl() の二重ラップ

変数にはすでに hsl() が含まれています。二重にラップすると hsl(hsl(...)) が生成されます。

誤り:background-color: hsl(var(--background)); 正しい例:background-color: var(--background);

#4 -- tailwind.config.ts の色

Tailwind v4 は設定ファイル内の theme.extend.colors を完全に無視します。ファイルを削除するか、空のままにしてください。components.json で "config": "" を設定してください。

#5 -- @theme inline の欠落

@theme inline がないと、Tailwind は CSS 変数を認識できません。bg-background のようなユーティリティクラスは生成されません。

誤り:

:root { --background: hsl(0 0% 100%); }
/* No @theme inline block -- bg-background won't exist */

正しい例:

:root { --background: hsl(0 0% 100%); }
@theme inline { --color-background: var(--background); }

#7 -- PostCSS と Vite プラグイン

誤り:

export default defineConfig({
  css: { postcss: './postcss.config.js' }  // Old v3 way
})

正しい例:

import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
  plugins: [react(), tailwindcss()]  // v4 way
})

#8 -- パスエイリアス

tsconfig.app.json に追加します:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": { "@/*": ["./src/*"] }
  }
}

#11 -- クラスを結合する cn() ユーティリティ

誤り:className={`base ${isActive && 'active'}`} 正しい例:className={cn("base", isActive && "active")}

@/lib/utils の cn() は、Tailwind クラスを適切に結合し、重複を解消します。

#12 -- Radix Select の空の値

Radix UI Select では空文字列の値を使用できません。value="" の代わりに value="placeholder" を使用してください。

#14 -- 必須の依存関係

{
  "dependencies": {
    "tailwindcss": "^4.1.0",
    "@tailwindcss/vite": "^4.1.0",
    "clsx": "^2.1.1",
    "tailwind-merge": "^3.3.1"
  },
  "devDependencies": {
    "@types/node": "^24.0.0"
  }
}

#17 -- tw-animate-css

Tailwind v4 では tailwindcss-animate は非推奨です。shadcn/ui のドキュメントには、まだ記載されている場合があります。ビルドの失敗やインポートエラーの原因になります。代わりに tw-animate-css または @tailwindcss/motion を使用してください。

#18 -- shadcn 初期化後の @layer base の重複

shadcn init は独自の @layer base ブロックを追加します。初期化を実行したら、すぐに src/index.css を確認し、重複するブロックがあれば1つにまとめてください。

誤り:

@layer base { body { background-color: var(--background); } }
@layer base { * { border-color: hsl(var(--border)); } }  /* duplicate from shadcn */

正しい例:

@layer base {
  * { border-color: var(--border); }
  body { background-color: var(--background); color: var(--foreground); }
}
予防チェックリスト
  • tailwind.config.ts ファイルがない(または空である)
  • components.json に "config": "" が設定されている
  • :root 内のすべての色が hsl() でラップされている
  • @theme inline ですべての変数がマッピングされている
  • @layer base が :root を囲んでいない
  • テーマプロバイダーがアプリをラップしている
  • ライト、ダーク、システムの各モードでテスト済みである
  • すべてのテキストに十分なコントラストがある

ダークモードのテストチェックリスト

  • ライトモードが正しく表示される
  • ダークモードが正しく表示される
  • システムモードが OS の設定に従う
  • ページを更新してもテーマが保持される
  • 切り替えコンポーネントに現在の状態が表示される
  • すべてのテキストに適切なコントラストがある
  • 読み込み時に誤ったテーマが一瞬表示されない
  • シークレットモードでも動作する(適切なフォールバックがある)

アセットファイル

assets/ ディレクトリからコピーします:

  • index.css -- すべての色変数を含む完全な CSS
  • components.json -- shadcn/ui v4 の設定
  • vite.config.ts -- Vite + Tailwind プラグイン
  • theme-provider.tsx -- ダークモードプロバイダー
  • utils.ts -- cn() ユーティリティ

参考ファイル

  • references/migration-guide.md -- v3 から v4 への移行ガイド

公式ドキュメント

コメント