mcpField
S
shadcn-tailwind

shadcn-tailwind

github.com/tenequmデザイン・UI40128 回インストール5 日前に更新
リポジトリ

shadcn-tailwind について

Tailwind CSS v4とshadcn/uiでアクセシブルなUIを作る開発者向けのスタイリングスキルです。CSSファーストの設定、セマンティックなテーマ、コンポーネント作成の指針を扱います。

主な機能

  1. 01Tailwind v4のCSSファースト設定
  2. 02shadcn/uiのコンポーネントパターン
  3. 03セマンティックカラーとテーマ
  4. 04レスポンシブとコンテナクエリ
  5. 05アクセシビリティとアニメーション指針

活用シーン

  1. 01旧設定をCSSファースト方式へ移行
  2. 02ダークモード対応UIの構築
  3. 03一貫したshadcn/uiコンポーネント作成

インストール

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

$npx skills add https://github.com/tenequm/skills --skill shadcn-tailwind

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

同梱ファイル

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

LICENSE.txt
references/
components.md
theming.md

詳細

Tailwind CSS によるスタイリング

Tailwind CSS v4 のユーティリティクラスと shadcn/ui のコンポーネントパターンを使用して、アクセシブルな UI を構築します。**Tailwind v4 は CSS ファーストの設定のみを使用します。tailwind.config.js/tailwind.config.ts は絶対に作成・変更しないでください。**プリミティブライブラリとして Radix UI(デフォルト)または Base UI をサポートします。

重要なルール

tailwind.config.js は使用禁止 — CSS ファーストのみ

Tailwind v4 ではすべてを CSS で設定します。JS/TS の設定は次のように移行してください。

  • theme.extend.colors → @theme { --color-*: ... }
  • plugins → @plugin "..." または @utility
  • content → @source "..."
  • tailwindcss-animate → @import "tw-animate-css"
  • @layer utilities → @utility name { ... }
常にセマンティックカラーのトークンを使用する
// CORRECT - respects themes and dark mode
<div className="bg-primary text-primary-foreground">

// WRONG - breaks theming
<div className="bg-blue-500 text-white">

bg-* と text-*-foreground は必ず組み合わせてください。success/warning/info の拡張については、theming.md を参照してください。

クラス名を動的に組み立てない
// WRONG - breaks Tailwind scanner
<div className={`bg-${color}-500`}>

// CORRECT - complete strings via lookup
const colorMap = { red: "bg-red-500", blue: "bg-blue-500" } as const
<div className={colorMap[color]}>
cn() のマージ順序

デフォルトを先に指定し、利用側の className を最後に指定します(tailwind-merge は後勝ちです)。

className={cn(buttonVariants({ variant, size }), className)}  // correct
className={cn(className, buttonVariants({ variant, size }))}  // wrong
アニメーションのパフォーマンス
// WRONG - transition-all causes layout thrashing
<div className="transition-all duration-300">

// CORRECT - transition only what changes
<div className="transition-colors duration-200">

// CORRECT - respect reduced motion
<div className="motion-safe:animate-fade-in">
@theme と @theme inline の違い
  • @theme — 静的なトークン。プラグインで上書きできます
  • @theme inline — CSS 変数を参照し、ダークモードの変更に追従します
@theme { --color-brand: oklch(0.6 0.2 250); }          /* static */
@theme inline { --color-primary: var(--primary); }       /* dynamic */

その他の注意点は components.md、カラーシステムのリファレンスは theming.md を参照してください。

基本パターン

テーマ設定用の CSS 変数

shadcn/ui では、セマンティックな CSS 変数を Tailwind のユーティリティにマッピングします。

/* globals.css - Light mode */
:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --border: oklch(0.922 0 0);
  --radius: 0.5rem;
}

/* Dark mode */
.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
}

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

コンポーネントでの使用方法:

// Background colors omit the "-background" suffix
<div className="bg-primary text-primary-foreground">
<div className="bg-muted text-muted-foreground">
<div className="bg-destructive text-destructive-foreground">
コンポーネントの作成パターン

コンポーネントには data-slot 属性を使用した通常の関数を使います(React 19 では forwardRef は不要です)。

import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"

const buttonVariants = cva(
  "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
        destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
        outline: "border border-input bg-background hover:bg-accent",
        ghost: "hover:bg-accent hover:text-accent-foreground",
        link: "text-primary underline-offset-4 hover:underline",
      },
      size: {
        default: "h-9 px-4 py-2",
        sm: "h-8 px-3 text-xs",
        lg: "h-10 px-8",
        icon: "size-9",
      },
    },
    defaultVariants: { variant: "default", size: "default" },
  }
)

// Plain function with React.ComponentProps (not forwardRef)
function Button({
  className,
  variant,
  size,
  ...props
}: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants>) {
  return (
    <button
      data-slot="button"
      className={cn(buttonVariants({ variant, size, className }))}
      {...props}
    />
  )
}

// Usage
<Button variant="outline" size="sm">Click me</Button>

data-icon によるアイコンの間隔調整:

<Button>
  <Spinner data-icon="inline-start" />
  Generating...
</Button>

<Button>
  <CheckIcon data-slot="icon" />
  Save Changes
</Button>
レスポンシブデザイン

モバイルファーストのブレークポイント:

// Stack on mobile, grid on tablet+
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">

// Hide on mobile
<div className="hidden md:block">

// Different layouts per breakpoint
<div className="flex flex-col md:flex-row lg:gap-8">
  <aside className="w-full md:w-64">
  <main className="flex-1">
</div>

// Responsive text sizes
<h1 className="text-3xl md:text-4xl lg:text-5xl">
コンテナクエリ

Tailwind v4 で標準サポートされているため、プラグインは不要です。

<div className="@container">
  <div className="grid gap-4 @sm:grid-cols-2 @lg:grid-cols-3">
    Responds to container width, not viewport
  </div>
</div>

// Named containers
<div className="@container/sidebar">
  <nav className="hidden @md/sidebar:block">
ダークモード
// Use dark: prefix - but prefer semantic colors over manual dark: overrides
<div className="bg-background text-foreground">          // auto dark mode
<div className="bg-white dark:bg-black">                 // manual override

// Use next-themes for toggle: useTheme() → setTheme("dark" | "light")
// Always add suppressHydrationWarning to <html> to prevent flash

一般的なコンポーネントパターン

カード
<div className="rounded-xl border bg-card text-card-foreground shadow">
  <div className="flex flex-col space-y-1.5 p-6">
    <h3 className="font-semibold leading-none tracking-tight">Title</h3>
    <p className="text-sm text-muted-foreground">Description</p>
  </div>
  <div className="p-6 pt-0">Content</div>
  <div className="flex items-center p-6 pt-0">Footer</div>
</div>
フォームフィールド
<div className="space-y-2">
  <label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
    Email
  </label>
  <input
    type="email"
    className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
  />
  <p className="text-sm text-muted-foreground">Helper text</p>
</div>
バッジ
const badgeVariants = cva(
  "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors",
  {
    variants: {
      variant: {
        default: "border-transparent bg-primary text-primary-foreground shadow",
        secondary: "border-transparent bg-secondary text-secondary-foreground",
        destructive: "border-transparent bg-destructive text-destructive-foreground",
        outline: "text-foreground",
      },
    },
  }
)

レイアウトパターン

中央揃えのレイアウト
<div className="flex min-h-screen items-center justify-center">
  <div className="w-full max-w-md space-y-8 p-8">
    {/* Content */}
  </div>
</div>
サイドバーのレイアウト
<div className="flex h-screen">
  <aside className="w-64 border-r bg-muted/40">Sidebar</aside>
  <main className="flex-1 overflow-auto">Content</main>
</div>
ダッシュボードのグリッド
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
  <Card className="col-span-2">Wide card</Card>
  <Card>Regular</Card>
  <Card>Regular</Card>
  <Card className="col-span-4">Full width</Card>
</div>

アクセシビリティパターン

フォーカスの可視化
<button className="focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">
スクリーンリーダー専用
<span className="sr-only">Close dialog</span>
無効状態
<button className="disabled:cursor-not-allowed disabled:opacity-50" disabled>

Tailwind v4 の機能

CSS ファーストの設定
@import "tailwindcss";

/* Custom utilities (replaces @layer utilities) */
@utility tab-highlight-none {
  -webkit-tap-highlight-color: transparent;
}

/* Custom variants */
@custom-variant pointer-fine (@media (pointer: fine));

/* Source control */
@source inline("{hover:,}bg-red-{50,100,200}");
@source not "./legacy";
@theme ディレクティブ
@theme {
  --color-primary: oklch(0.205 0 0);
  --font-sans: "Inter", system-ui;
}

/* With CSS variables (shadcn/ui pattern) */
@theme inline {
  --color-primary: var(--primary);
}
アニメーション
@import "tw-animate-css";
<div className="animate-fade-in">
<div className="animate-slide-in-from-top">
v4.1 の機能
// Text shadows
<h1 className="text-shadow-sm text-4xl font-bold">

// Gradient masks for fade effects
<div className="mask-linear-to-b">Fades to transparent at bottom</div>

// Pointer-aware sizing
<button className="pointer-fine:py-1 pointer-coarse:py-3">

// Form validation after user interaction
<input className="user-valid:border-success user-invalid:border-destructive" />

// Overflow wrap for long strings
<p className="overflow-wrap-anywhere">verylongwordthatneedstowrap</p>
v4.2 の機能(2026 年 2 月)
// Logical block properties (RTL/writing-mode aware)
<div className="pbs-4 pbe-8 mbs-2">
<div className="border-bs-2 border-be">

// Logical sizing (replaces w-*/h-* for logical layouts)
<div className="inline-full block-screen">

// Font feature settings
<p className="font-features-['tnum','liga']">Tabular numbers</p>

// New color palettes: mauve, olive, mist, taupe
<div className="bg-mauve-100 text-olive-900">

非推奨:start-*/end-* は非推奨となり、inset-s-*/inset-e-* に置き換えられました。

OKLCH カラー

shadcn/ui のカラーはすべて OKLCH 形式 oklch(lightness chroma hue) を使用します。Lightness は 0〜1、chroma は 0〜0.4(0 はグレー)、hue は 0〜360 です。基本パレット:Neutral、Zinc、Slate、Stone、Gray。パレット全体と OKLCH のリファレンスについては、theming.md を参照してください。

ベストプラクティス

セマンティックカラーを優先する
// Good - uses theme
<div className="bg-background text-foreground">

// Avoid - hardcoded
<div className="bg-white text-black dark:bg-zinc-950">
関連するユーティリティをまとめる
<div className="
  flex items-center justify-between
  rounded-lg border
  bg-card text-card-foreground
  p-4 shadow-sm
  hover:bg-accent
">
任意の値を避ける
// Prefer design tokens
<div className="p-4 text-sm">

// Avoid when unnecessary
<div className="p-[17px] text-[13px]">

インストールと CLI

# Create new project with visual style + primitive selection
npx shadcn create

# Initialize in existing project
pnpm dlx shadcn@latest init

# Add components
pnpm dlx shadcn@latest add button card form

# Add from community registries
npx shadcn add @acme/button @internal/auth-system

# View/search registries
npx shadcn view @acme/auth-system
npx shadcn search @tweakcn -q "dark"
npx shadcn list @acme

# Add MCP server for AI integration
npx shadcn@latest mcp init

# Update existing components
pnpm dlx shadcn@latest add button --overwrite
ビジュアルスタイル

npx shadcn create では、組み込みのビジュアルスタイルを 5 種類利用できます。

  • Vega — shadcn/ui のクラシックな外観
  • Nova — コンパクトで、パディングを抑えたスタイル
  • Maia — ソフトで丸みがあり、ゆとりのある間隔
  • Lyra — 四角くシャープで、等幅フォントとの相性が良いスタイル
  • Mira — データ量の多いインターフェース向けの密度の高いスタイル

これらは選択したスタイルに合わせてコンポーネントコードを書き換えます(CSS 変数だけではありません)。

トラブルシューティング

カラーが更新されない: globals.css の CSS 変数を確認 → @theme inline にマッピングが含まれていることを確認 → ビルドキャッシュをクリアします。

読み込み時にダークモードがちらつく: <html> タグに suppressHydrationWarning を追加し、attribute="class" を指定した ThemeProvider でアプリをラップしてください。

tailwind.config.js が見つかった: 削除してください。npx @tailwindcss/upgrade を実行すると、CSS ファーストの設定に自動移行できます。カスタマイズはすべて、CSS ファイル内の @theme、@utility、@plugin を使って行ってください。

クラスが検出されない: @source ディレクティブがコンポーネントのパスを網羅しているか確認してください。クラス名を動的に組み立てないでください(「重要なルール」を参照)。

コンポーネントのパターン

コンポーネントのパターンの詳細は、components.md をご覧ください。

  • コンポジション:asChild パターン、data-slot 属性
  • タイポグラフィ:見出しのスケール、プローズスタイル、インラインコード
  • フォーム:React Hook Form + Zod、FieldSet/FieldGroup を備えた Field コンポーネント
  • アイコン:data-icon 属性を使用する Lucide アイコン
  • 入力:OTP、ファイル、グループ化された入力
  • ダイアログ:モーダルのパターンとコンポジション
  • データテーブル:TanStack テーブルの統合
  • トースト:Sonner の通知
  • 注意点:cn() の順序、フォームの defaultValues、ダイアログのネスト、sticky、サーバー/クライアント

リソース

色システムの完全なリファレンスは、theming.md をご覧ください。

  • @theme と @theme inline(ダークモードでは重要)
  • ステータスカラーの拡張(success、warning、info)
  • Z-index のスケールとアニメーショントークン
  • すべての基本パレット(Neutral、Zinc、Slate、Stone、Gray)

まとめ

重要な概念:

  • v4 は CSS ファーストのみ - tailwind.config.js はなく、設定はすべて CSS 内に記述します
  • セマンティックカラーのみ - 生のパレット(bg-blue-500)は使用せず、必ず bg-primary を使用します
  • bg-* と text-*-foreground は常に組み合わせます
  • クラス名を動的に生成しない - 完全な文字列を使ったオブジェクト参照を使用します
  • cn() の順序 - デフォルトを先にし、利用側の className を最後にします
  • transition-all は使用しない - 特定のプロパティのみをトランジションします
  • 動的なテーマ設定には @theme inline、静的なトークンには @theme を使用します
  • data-slot を持つ通常の関数としてコンポーネントを作成します(React 19)
  • コンポーネントのバリアントには CVA を適用します
  • アニメーションには motion-safe: / motion-reduce: を使用します
  • プリミティブライブラリとして Radix UI または Base UI を選択します

このスキルは Tailwind CSS v4.2 と shadcn/ui を対象としています。コンポーネント固有の例は components.md、色システムについては theming.md をご覧ください。

コメント