modern-ui-designer について
Tailwind CSSとshadcn/uiを使う開発者向けのUI設計スキルです。ミニマルな視覚設計に加え、8px間隔のグリッド、レスポンシブ設計、WCAGのアクセシビリティ指針を扱います。
主な機能
- 01Tailwind CSSとshadcn/uiのパターン
- 02ミニマルな視覚的階層
- 038pxグリッドの間隔指針
- 04モバイルファーストのレスポンシブ設計
- 05WCAGアクセシビリティの実践
活用シーン
- 01統一感のあるページやコンポーネントの設計
- 02色のコントラストとキーボード操作の確認
- 03Tailwind CSSによるレスポンシブUIの構築
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sitechfromgeorgia/ georgian-distribution-system --skill modern-ui-designerインストール後、Claude Code で/modern-ui-designerを入力して読み込まれたか確認します。
同梱ファイルSETUP_GUIDE.md
詳細
モダン UI デザイナー — 2025 年の標準
概要
このスキルでは、2025 年のモダンな標準に沿った、世界水準の UI デザインを作成するための包括的なガイダンスを提供します。Tailwind CSS のベストプラクティス、shadcn/ui のコンポーネントパターン、クリーンでミニマルなデザイン原則、8px グリッドのスペーシングシステム、モバイルファーストのレスポンシブデザイン、WCAG のアクセシビリティ準拠を網羅しています。
基本理念:プロフェッショナルで、ミニマル、アクセシブル、かつ一貫性のあるデザイン。
デザイン原則(2025 年)
1. クリーンなミニマリズム
基本ルール:
- 不要なものを取り除く:すべての要素に明確な目的を持たせます
- 余白は強力です:ゆとりのあるスペーシングは読みやすさを高め、認知負荷を軽減します
- コンテンツファースト:デザインはコンテンツに奉仕するものであり、その逆ではありません
- 視覚的階層:サイズ、色、スペーシングを使って注目を誘導します
- 派手さより控えめさ:プロフェッショナルなデザインでは節度を保ちます
避けること:
- ❌ 虹色のグラデーションや過剰な色使い
- ❌ 機能のない装飾要素
- ❌ 複雑なパターンやテクスチャ
- ❌ 要素を詰め込みすぎたインターフェース
- ❌ 一貫性のないスペーシング
取り入れること:
- ✅ ニュートラルなカラーパレット(グレー+アクセントカラー1色)
- ✅ ゆとりのある余白と、窮屈さのないレイアウト
- ✅ 明確な階層を持つクリーンなタイポグラフィ
- ✅ 控えめなシャドウとボーダー
- ✅ 一貫した 8px グリッドシステム
2. 視覚的階層のベストプラクティス
サイズ:
- 見出しと本文には大きなサイズ差をつけます
- 本文は最低 16px(読みやすさを考慮して 18px を推奨)
- 見出しのスケール:48px → 32px → 24px → 20px → 18px → 16px
- Tailwind の text-* ユーティリティを使用します:text-6xl、text-4xl、text-2xl、text-xl、text-lg、text-base
色:
- 重要度を示すために色を戦略的に使います
- 主要なアクション:アクセントカラー
- 副次的なアクション:ニュートラルなグレー
- 無効状態:コントラストを抑えたグレー
- エラー状態:赤(アクセシブルなコントラスト)
- 成功状態:緑(アクセシブルなコントラスト)
ウェイト:
- 見出し:font-bold(700)または font-semibold(600)
- 本文:font-normal(400)または font-medium(500)
- キャプション:font-light(300)を慎重に使用
スペーシング:
- 大きなスペーシング(32px 以上)で主要なセクションを区切ります
- 中程度のスペーシング(16〜24px)で関連するコンテンツをまとめます
- 小さなスペーシング(8px)を密接に関連する項目に使います
- 内側 ≤ 外側のルール:要素内部のスペースは、要素間のスペースより小さくします
8px グリッドシステム
基本概念
すべてのスペーシング、サイズ、レイアウトには 8 の倍数を使用します:
- 基本単位:8px、16px、24px、32px、40px、48px、56px、64px、72px、80px
- 半単位:4px(アイコン、ボーダー、または微調整に限って使用)
- 使用禁止:7px、13px、25px など、規則に沿わない値
なぜ 8px なのか?
- デバイスとの互換性:ほとんどの画面解像度は 8 で割り切れます
- スケーリング:@1x、@2x、@3x のディスプレイで適切に機能します
- 視覚的一貫性:目測しやすく、リズムを維持しやすくなります
- 開発者にとって使いやすい:デザインからコードへの変換時の誤差を減らせます
Tailwind CSS のスペーシングスケール
Tailwind のスペーシングスケールは 8px グリッドにぴったり合います:
0 → 0px
0.5 → 2px (exception for borders)
1 → 4px (half unit)
2 → 8px (base)
3 → 12px (1.5 units, use sparingly)
4 → 16px (2 units)
5 → 20px (2.5 units, use sparingly)
6 → 24px (3 units)
8 → 32px (4 units)
10 → 40px (5 units)
12 → 48px (6 units)
16 → 64px (8 units)
20 → 80px (10 units)
24 → 96px (12 units)
32 → 128px (16 units)
スペーシングに推奨する値:
- パディング:p-2、p-4、p-6、p-8、p-12、p-16
- マージン:m-2、m-4、m-6、m-8、m-12、m-16
- ギャップ:gap-2、gap-4、gap-6、gap-8
スペーシングの階層(近接の原則)
密接に関連する項目(8px - 16px):
<div class="space-y-2">
<h3 class="text-xl font-semibold">Heading</h3>
<p class="text-gray-600">Subheading</p>
</div>
関連するコンテンツ(24px - 32px):
<div class="space-y-6">
<section></section>
<section></section>
</div>
セクションを分ける場合(48px - 64px):
<div class="space-y-12 md:space-y-16">
<section></section>
<section></section>
</div>
8px グリッドを使ったコンポーネントのサイズ設定
ボタン:
- 小:h-8(32px)、px-3 py-1.5
- 中:h-10(40px)、px-4 py-2
- 大:h-12(48px)、px-6 py-3
- 特大:h-14(56px)、px-8 py-4
入力フィールド:
- 高さ:h-10(40px)または h-12(48px)
- パディング:px-3 py-2 または px-4 py-3
カード:
- パディング:コンテンツに応じて p-4、p-6、または p-8
- 角丸:rounded-md(6px)、rounded-lg(8px)、rounded-xl(12px)
カラーシステム(ニュートラル+アクセント)
ニュートラルなパレットのアプローチ
基本戦略:グレースケール+アクセントカラー1色
グレースケール(Tailwind):
slate-50 → Backgrounds
slate-100 → Subtle backgrounds
slate-200 → Borders, dividers
slate-300 → Disabled text
slate-400 → Placeholder text
slate-500 → Secondary text
slate-600 → Body text
slate-700 → Headings
slate-800 → Emphasis
slate-900 → Maximum contrast
アクセントカラーの選択:
- ブランドカラーを1色選びます
- 用途:主要ボタン、リンク、アクティブ状態、強調表示
- 必要なシェード:50、100、200、300、400、500、600、700、800、900
- 例:主要カラーに blue-600、ホバー時に blue-700
セマンティックカラー(最小限の使用)
<div class="bg-green-50 text-green-700 border border-green-200">
<div class="bg-yellow-50 text-yellow-800 border border-yellow-200">
<div class="bg-red-50 text-red-700 border border-red-200">
<div class="bg-blue-50 text-blue-700 border border-blue-200">
ダークモードのサポート
<div class="bg-white dark:bg-slate-900 text-slate-900 dark:text-slate-50">
<div class="border border-slate-200 dark:border-slate-800">
<div class="bg-slate-50 dark:bg-slate-800">
<button class="bg-blue-600 hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600">
色のコントラストに関するルール(WCAG)
テキストのコントラスト比:
- 通常のテキスト(< 24px):最低 4.5:1
- 大きなテキスト(≥ 24px):最低 3:1
- UI コンポーネントとグラフィック:最低 3:1
安全な組み合わせ:
✅ slate-900 on white → 18.9:1
✅ slate-700 on white → 8.6:1
✅ slate-600 on white → 6.2:1
✅ blue-600 on white → 5.4:1
❌ slate-400 on white → 2.9:1 (fails)
❌ slate-300 on white → 1.7:1 (fails)
Tailwind CSS のベストプラクティス(2025)
1. ユーティリティファーストのアプローチ
推奨:
<button class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
transition-colors duration-200">
Click me
</button>
非推奨:
/* ❌ Avoid custom CSS unless absolutely necessary */
.custom-button {
padding: 0.5rem 1rem;
background: #3b82f6;
/* ... */
}
2. @apply を使ったコンポーネントの抽出(控えめに)
@apply を使用するのは、次の場合に限ります:
- 10回以上使用されるコンポーネント
- サードパーティライブラリのオーバーライド
- 印刷用スタイルシート
/* ✅ Good use of @apply */
@layer components {
.btn-primary {
@apply px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700
focus:outline-none focus:ring-2 focus:ring-blue-500;
}
}
3. レスポンシブデザイン(モバイルファースト)
ブレークポイント:
sm: 640px → Small tablets
md: 768px → Tablets
lg: 1024px → Desktop
xl: 1280px → Large desktop
2xl: 1536px → Extra large
パターン:
<div class="p-4 md:p-6 lg:p-8">
<h1 class="text-2xl md:text-3xl lg:text-4xl">
Responsive Heading
</h1>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6">
</div>
4. 状態バリアント
ホバー、フォーカス、アクティブ:
<button class="bg-blue-600 hover:bg-blue-700 active:bg-blue-800
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
disabled:opacity-50 disabled:cursor-not-allowed">
ダークモード:
<div class="bg-white dark:bg-slate-900
text-slate-900 dark:text-slate-50
border border-slate-200 dark:border-slate-800">
5. クラスの整理(順序を統一)
標準の順序:
- レイアウト(display、position、overflow)
- サイズ(width、height)
- 余白(margin、padding)
- タイポグラフィ(font、text)
- 視覚効果(background、border)
- エフェクト(shadow、opacity)
- トランジション
- バリアント(hover、focus、dark)
<div class="
flex items-center justify-between
w-full max-w-screen-lg
px-4 py-3 my-2
text-lg font-medium text-gray-800
bg-white rounded shadow
hover:shadow-md
transition-shadow
">
6. JIT モードとパージ
JIT(Just-In-Time)モードを常に有効にします:
// tailwind.config.js
module.exports = {
content: [
'./src/**/*.{html,js,jsx,ts,tsx}',
'./components/**/*.{html,js,jsx,ts,tsx}',
],
// ... rest of config
}
利点:
- CSS バンドルのサイズを縮小
- 任意の値を使用可能:
w-[373px] - すべてのバリアントを利用可能
- ビルド時間を短縮
shadcn/ui のコンポーネントパターン
アーキテクチャの理解
shadcn/ui = Radix UI + Tailwind CSS + CVA:
- Radix UI:スタイルなしのアクセシブルなプリミティブ
- Tailwind CSS:ユーティリティファーストのスタイリング
- CVA (Class Variance Authority):バリアント管理
基本パターン:コピー、所有、カスタマイズ
パッケージではありません:コンポーネントのソースをプロジェクトにコピーします
- コードを完全に所有
- 互換性を損なう更新がない
- 完全なカスタマイズ
- 型安全なバリアント
コンポーネントの構成例
// Button.tsx
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
// Base styles (always applied)
"inline-flex items-center justify-center rounded-lg font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-slate-900 text-slate-50 hover:bg-slate-800",
outline: "border border-slate-200 bg-transparent hover:bg-slate-100",
ghost: "hover:bg-slate-100",
},
size: {
sm: "h-8 px-3 text-sm",
md: "h-10 px-4",
lg: "h-12 px-6 text-lg",
},
},
defaultVariants: {
variant: "default",
size: "md",
},
}
)
interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {}
export const Button = ({ className, variant, size, ...props }: ButtonProps) => {
return (
<button
className={cn(buttonVariants({ variant, size }), className)}
{...props}
/>
)
}
shadcn/ui のベストプラクティス
1. クラスのマージには cn() ユーティリティを使用します:
import { cn } from "@/lib/utils"
// Allows className override
<Button className={cn("custom-class", conditionalClass && "other-class")} />
2. デザインシステムとの統合:
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
// ... more design tokens
},
},
},
}
3. テーマ設定には CSS 変数を使用します:
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--radius: 0.5rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--primary: 217.2 91.2% 59.8%;
--primary-foreground: 222.2 47.4% 11.2%;
--border: 217.2 32.6% 17.5%;
}
よく使われるパターン
ラベル付きフォームフィールド:
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
placeholder="[email protected]"
className="w-full"
/>
<p className="text-sm text-slate-500">
We'll never share your email.
</p>
</div>
カードレイアウト:
<Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>Card description goes here</CardDescription>
</CardHeader>
<CardContent>
</CardContent>
<CardFooter>
</CardFooter>
</Card>
ダイアログパターン:
<Dialog>
<DialogTrigger asChild>
<Button variant="outline">Open Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Dialog Title</DialogTitle>
<DialogDescription>
Dialog description text
</DialogDescription>
</DialogHeader>
<DialogFooter>
<Button variant="outline">Cancel</Button>
<Button>Confirm</Button>
</DialogFooter>
</DialogContent>
</Dialog>
アクセシビリティ(WCAG 2.2 準拠)
4つの原則(POUR)
1. 知覚可能:
- 画像にテキストによる代替情報を付ける
- 動画にキャプションを付ける
- コンテンツ構造を柔軟にする
- 十分な色のコントラストを確保する
2. 操作可能:
- キーボードで操作できる
- キーボードトラップを設けない
- 操作に十分な時間を確保する
- 発作を誘発するコンテンツを設けない
3. 理解可能:
- 読みやすいテキスト
- 予測可能な動作
- 入力支援とエラー防止
4. 堅牢:
- 支援技術との互換性
- 有効な HTML
- 適切な ARIA 属性
重要な要件
キーボード操作:
<button
class="focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
>
Accessible Button
</button>
<a href="#main-content" class="sr-only focus:not-sr-only focus:absolute focus:top-0 focus:left-0">
Skip to main content
</a>
フォーカスインジケーター(WCAG 2.2):
- 視認できること
- 最低 2px の太さ
- 背景に対するコントラスト比が 3:1 であること
focus:ring-2とfocus:ring-offset-2を使用します
タッチターゲット:
- 最低 44x44px(WCAG 2.1)
- 最低 24x24px の間隔(WCAG 2.2)
- インタラクティブ要素には
min-h-[44px] min-w-[44px]を使用します
色のコントラスト:
<p class="text-slate-700">Body text</p>
<button class="bg-blue-600 text-white">Action</button>
<p class="text-slate-400">Fails WCAG</p>
セマンティック HTML:
<header>
<nav aria-label="Main navigation">
<ul>
<li><a href="/">Home</a></li>
</ul>
</nav>
</header>
<main>
<article>
<h1>Page Title</h1>
<section>
<h2>Section Heading</h2>
</section>
</article>
</main>
<footer>
</footer>
ARIA ラベル:
<button aria-label="Close dialog" class="...">
<XIcon className="h-4 w-4" aria-hidden="true" />
</button>
<label for="search" class="sr-only">Search</label>
<input id="search" type="search" />
<div role="status" aria-live="polite" aria-atomic="true">
Loading...
</div>
フォームのアクセシビリティ:
<form>
<div>
<label for="email" class="block text-sm font-medium mb-2">
Email
<span class="text-red-600" aria-label="required">*</span>
</label>
<input
id="email"
type="email"
required
aria-required="true"
aria-describedby="email-error"
aria-invalid={hasError ? "true" : "false"}
class="w-full"
/>
{hasError && (
<p id="email-error" class="text-sm text-red-600 mt-1" role="alert">
Please enter a valid email address
</p>
)}
</div>
</form>
モバイルファーストのレスポンシブデザイン
戦略
モバイル(320px - 640px)から始めます:
- 最小画面向けに最初に設計する
- タッチ操作に最適化する
- コンテンツの優先順位を明確にする
- 大きな画面向けに段階的に機能を拡張する
レスポンシブパターン
コンテナー幅:
<div class="container mx-auto px-4 md:px-6 lg:px-8 max-w-7xl">
</div>
タイポグラフィのスケール:
<h1 class="text-3xl md:text-4xl lg:text-5xl font-bold">
Responsive Heading
</h1>
<p class="text-base md:text-lg leading-relaxed">
Body text with responsive sizing
</p>
グリッドレイアウト:
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 lg:gap-6">
<div></div>
<div></div>
<div></div>
</div>
レスポンシブな Flexbox:
<div class="flex flex-col md:flex-row gap-4 md:gap-6">
<div class="flex-1"></div>
<div class="flex-1"></div>
</div>
表示の制御:
<div class="hidden md:block">
Desktop only content
</div>
<div class="block md:hidden">
Mobile only content
</div>
ナビゲーションパターン:
<nav>
<button class="md:hidden">
<MenuIcon />
</button>
<ul class="hidden md:flex md:space-x-4">
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
タイポグラフィシステム
フォントの選択
モダンでプロフェッショナルなフォント:
- サンセリフ:Inter、SF Pro、-apple-system、system-ui
- 等幅:JetBrains Mono、Fira Code、SF Mono
// tailwind.config.js
module.exports = {
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
mono: ['JetBrains Mono', 'monospace'],
},
},
},
}
文字サイズのスケール(8pxベース)
text-xs → 12px (line-height: 16px)
text-sm → 14px (line-height: 20px)
text-base → 16px (line-height: 24px) ← Body text default
text-lg → 18px (line-height: 28px)
text-xl → 20px (line-height: 28px)
text-2xl → 24px (line-height: 32px)
text-3xl → 30px (line-height: 36px)
text-4xl → 36px (line-height: 40px)
text-5xl → 48px (line-height: 48px)
text-6xl → 60px (line-height: 60px)
行の高さ
行の高さは必ず8px単位にしてください:
<p class="text-base leading-6">
<h2 class="text-3xl leading-9">
テキスト階層の例
<article class="space-y-6">
<h1 class="text-4xl md:text-5xl font-bold text-slate-900 leading-tight">
Article Title
</h1>
<p class="text-xl text-slate-600 leading-relaxed">
Engaging subtitle or description
</p>
<div class="flex items-center gap-4 text-sm text-slate-500">
<span>By Author Name</span>
<span>•</span>
<time datetime="2025-01-15">Jan 15, 2025</time>
</div>
<div class="prose prose-slate max-w-none">
<p class="text-base leading-relaxed text-slate-700">
Body paragraph with comfortable reading size and spacing...
</p>
</div>
</article>
シャドウとエレベーション
シャドウシステム(控えめでプロフェッショナル)
<div class="shadow-sm">
<div class="shadow">
<div class="shadow-md">
<div class="shadow-lg">
<div class="shadow-xl">
<div class="shadow-[0_2px_8px_rgba(0,0,0,0.08)]">
モダンなパターン:シャドウとボーダーを組み合わせます
<div class="border border-slate-200 shadow-sm rounded-lg">
</div>
エレベーションの状態
<div class="border border-slate-200 shadow-sm hover:shadow-md
transition-shadow duration-200 rounded-lg">
Hover me
</div>
角丸のガイドライン
一貫した角丸
rounded-none → 0px
rounded-sm → 2px (subtle, modern)
rounded → 4px (default)
rounded-md → 6px (cards)
rounded-lg → 8px (buttons, inputs) ← Preferred
rounded-xl → 12px (large cards)
rounded-2xl → 16px (hero sections)
rounded-full → 9999px (circles, pills)
2025年のトレンド:大きく、柔らかな角丸(8px - 12px)
<button class="px-4 py-2 bg-blue-600 text-white rounded-lg">
<div class="border border-slate-200 rounded-xl p-6">
<img class="h-10 w-10 rounded-full" />
コンポーネントのデザイン例
モダンなボタン
<button class="
inline-flex items-center justify-center
h-10 px-4
text-base font-medium
bg-blue-600 text-white
rounded-lg
hover:bg-blue-700
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
active:bg-blue-800
disabled:opacity-50 disabled:cursor-not-allowed
transition-colors duration-200
">
Primary Action
</button>
<button class="
inline-flex items-center justify-center
h-10 px-4
text-base font-medium
border border-slate-300 bg-white text-slate-700
rounded-lg
hover:bg-slate-50
focus:outline-none focus:ring-2 focus:ring-slate-500 focus:ring-offset-2
disabled:opacity-50 disabled:cursor-not-allowed
transition-colors duration-200
">
Secondary Action
</button>
<button class="
inline-flex items-center justify-center
h-10 px-4
text-base font-medium text-slate-700
rounded-lg
hover:bg-slate-100
focus:outline-none focus:ring-2 focus:ring-slate-500 focus:ring-offset-2
transition-colors duration-200
">
Ghost Button
</button>
モダンな入力フィールド
<div class="space-y-2">
<label
for="email"
class="block text-sm font-medium text-slate-700"
>
Email address
</label>
<input
id="email"
type="email"
placeholder="[email protected]"
class="
w-full h-10 px-3
text-base text-slate-900 placeholder:text-slate-400
bg-white
border border-slate-300 rounded-lg
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent
disabled:bg-slate-50 disabled:text-slate-500 disabled:cursor-not-allowed
transition-colors duration-200
"
/>
<p class="text-sm text-slate-500">
We'll never share your email with anyone else.
</p>
</div>
モダンなカード
<div class="
bg-white
border border-slate-200
rounded-xl
shadow-sm hover:shadow-md
transition-shadow duration-200
overflow-hidden
">
<div class="aspect-video bg-slate-100">
<img
src="..."
alt="..."
class="w-full h-full object-cover"
/>
</div>
<div class="p-6 space-y-4">
<h3 class="text-xl font-semibold text-slate-900">
Card Title
</h3>
<p class="text-base text-slate-600 leading-relaxed">
Card description goes here with comfortable reading spacing.
</p>
<div class="flex items-center gap-3">
<button class="...">Primary</button>
<button class="...">Secondary</button>
</div>
</div>
</div>
モダンなナビゲーション
<header class="sticky top-0 z-50 bg-white border-b border-slate-200">
<nav class="container mx-auto px-4 md:px-6">
<div class="flex items-center justify-between h-16">
<a href="/" class="flex items-center gap-2">
<img src="logo.svg" alt="Logo" class="h-8 w-8" />
<span class="text-xl font-bold text-slate-900">Brand</span>
</a>
<ul class="hidden md:flex items-center gap-8">
<li>
<a href="/" class="text-sm font-medium text-slate-700 hover:text-slate-900">
Home
</a>
</li>
<li>
<a href="/about" class="text-sm font-medium text-slate-700 hover:text-slate-900">
About
</a>
</li>
<li>
<a href="/contact" class="text-sm font-medium text-slate-700 hover:text-slate-900">
Contact
</a>
</li>
</ul>
<button class="hidden md:inline-flex ...">
Get Started
</button>
<button class="md:hidden" aria-label="Open menu">
<MenuIcon class="h-6 w-6" />
</button>
</div>
</nav>
</header>
避けるべきアンチパターン
❌ これらは避けてください
1. 一貫性のない余白:
<div class="mt-3 mb-5 px-7">
<div class="my-4 px-6">
2. 不十分な色のコントラスト:
<p class="text-slate-400">Important text</p>
<p class="text-slate-700">Important text</p>
3. フォーカススタイルの欠落:
<button class="outline-none">
<button class="focus:outline-none focus:ring-2 focus:ring-blue-500">
4. セマンティックでないHTML:
<div onClick="navigate()">Home</div>
<a href="/home">Home</a>
5. 小さすぎるタッチターゲット:
<button class="p-1">×</button>
<button class="p-3 min-h-[44px] min-w-[44px]">×</button>
6. 過剰に装飾されたデザイン:
<div class="bg-gradient-to-r from-purple-500 via-pink-500 to-red-500
shadow-2xl border-4 border-yellow-400 rounded-3xl">
<div class="bg-white border border-slate-200 rounded-lg shadow-sm">
7. 固定ピクセル幅:
<div class="w-[800px]">
<div class="w-full max-w-3xl">
簡易レビューチェックリスト
デザインレビュー(開発前)
ビジュアルデザイン:
- ニュートラルなカラーパレット(グレー+アクセントカラー1色)を使用している
- すべての余白とサイズに8pxグリッドを適用している
- 一貫した角丸(8px - 12px)を維持している
- 控えめなシャドウ(強いドロップシャドウではない)を使用している
- タイポグラフィの階層が明確である
- 余白が十分にあり、意図的に配置されている
レスポンシブ対応:
- モバイルファーストの設計アプローチを採用している
- タッチターゲットは最低44x44pxである
- ズームしなくてもテキストを読める
- すべてのブレークポイントでコンテンツが適切に再配置される
- モバイルでもナビゲーションが機能する
アクセシビリティ:
- 色のコントラストがWCAG 2.2に適合している(最低4.5:1)
- フォーカスインジケーターが見える(2pxのリング)
- セマンティックHTMLを正しく使用している
- アイコンのみのボタンにARIAラベルがある
- フォームのラベルが適切に関連付けられている
コンポーネント:
- ボタンにホバー、フォーカス、アクティブの各状態がある
- フォーム入力に検証状態がある
- ローディング状態が設計されている
- エラー状態が明確で、役立つ情報を提供している
- 空の状態が親しみやすい
開発レビュー(実装後)
技術面:
- Tailwindのクラスが一貫した順序で記述されている
- JITモードが有効で、パージが設定されている
- 絶対に必要な場合を除き、カスタムCSSを使用していない
- ダークモードに対応している
- パフォーマンスが最適化されている(遅延読み込みなど)
アクセシビリティテスト:
- キーボード操作で完全に使える
- スクリーンリーダーでテスト済み(NVDA/VoiceOver)
- ツールで色のコントラストを確認済み
- フォームが完全にアクセシブルである
- ARIA属性を正しく使用している
レスポンシブテスト:
- モバイルでテスト済み(375px、414px)
- タブレットでテスト済み(768px、1024px)
- デスクトップでテスト済み(1280px、1920px)
- タッチ操作が適切に機能する
- どの画面サイズでも横スクロールが発生しない
高度なテクニック
1. テーマ設定のためのTailwind CSS変数
@layer base {
:root {
/* Spacing */
--spacing-xs: 0.5rem; /* 8px */
--spacing-sm: 1rem; /* 16px */
--spacing-md: 1.5rem; /* 24px */
--spacing-lg: 2rem; /* 32px */
/* Colors */
--color-primary: 220 90% 56%;
--color-primary-hover: 220 90% 48%;
/* Border radius */
--radius-sm: 0.5rem; /* 8px */
--radius-md: 0.75rem; /* 12px */
--radius-lg: 1rem; /* 16px */
}
}
2. カスタムユーティリティクラス
@layer utilities {
/* Text balance for headings */
.text-balance {
text-wrap: balance;
}
/* Smooth scroll */
.scroll-smooth {
scroll-behavior: smooth;
}
/* Focus visible only */
.focus-visible-ring {
@apply focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500;
}
}
3. コンポーネント合成パターン
// Compose smaller components into larger ones
<Card>
<CardHeader>
<div className="flex items-center justify-between">
<div className="space-y-1">
<CardTitle>Dashboard</CardTitle>
<CardDescription>Welcome back</CardDescription>
</div>
<Button variant="outline" size="sm">
<SettingsIcon className="h-4 w-4" />
</Button>
</div>
</CardHeader>
<CardContent>
<Tabs defaultValue="overview">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
</TabsList>
<TabsContent value="overview" className="space-y-4">
{/* Content */}
</TabsContent>
</Tabs>
</CardContent>
</Card>
リソースとツール
デザインツール
- Figma:主要なデザインツール
- Tailwind CSS IntelliSense:VS Code拡張機能
- Headless UI:スタイルを持たないアクセシブルなコンポーネント
- Radix UI:shadcn/ui向けのプリミティブコンポーネント
アクセシビリティテスト
- WAVE:アクセシビリティテスト用のブラウザー拡張機能
- axe DevTools:自動アクセシビリティテスト
- Contrast Checker:WCAGの色のコントラストを確認
- NVDA/VoiceOver:スクリーンリーダーテスト
カラーツール
- Coolors:カラーパレットジェネレーター
- Tailwind Shades:Tailwindのカラースケールを生成
- Contrast Ratio:WebAIMのコントラストチェッカー
タイポグラフィ
- Typescale:文字サイズのスケールを生成
- Modular Scale:調和の取れたサイズを計算
- Google Fonts:無料のWebフォント
学習リソース
- Tailwind CSS Documentation:公式ドキュメント
- shadcn/ui Documentation:コンポーネントライブラリのドキュメント
- WCAG Guidelines:W3C のアクセシビリティ基準
- Refactoring UI:Tailwind の開発者によるデザインのヒント
まとめ
2025 年のモダン UI デザインの要点:
- クリーンなミニマリズム:不要なものを取り除き、余白を活用する
- 8px グリッドシステム:一貫性があり、拡張可能な余白とサイズ設定
- ニュートラルカラー+アクセントカラー:グレーを基調に、プライマリカラーを 1 色使う
- Tailwind CSS:ユーティリティファースト、JIT 対応、レスポンシブ
- shadcn/ui:コピーして所有できる、アクセシブルなコンポーネント
- WCAG 2.2:完全なキーボード操作対応とカラーコントラスト
- モバイルファースト:小さな画面からデザインし、拡張していく
- プロフェッショナルな仕上がり:控えめなシャドウ、柔らかな角、滑らかなトランジション
覚えておいてください:目標は、派手なデザインで印象づけることではなく、美しく、機能的で、アクセシブルで、使っていて心地よいインターフェースを作ることです。
このスキルを使用する場面
このスキルを有効にする場面:
- 新しい UI コンポーネントやページをデザインするとき
- モダンな基準に照らして既存のデザインをレビューするとき
- デザインシステムやコンポーネントライブラリを作成するとき
- Tailwind CSS や shadcn/ui を実装するとき
- アクセシビリティへの準拠を確保するとき
- レスポンシブレイアウトを最適化するとき
- ビジュアルデザインの問題をトラブルシューティングするとき
- UI のベストプラクティスを教えたり、ドキュメント化したりするとき
出力形式:常にコード例を提示し、デザイン上の判断を説明し、該当する場合は具体的な Tailwind ユーティリティや shadcn/ui コンポーネントを参照してください。