visual-design-foundations について
ビジュアルシステムを作成・評価するデザイナーや開発者向けのデザインスキルです。タイポグラフィ、色、余白、アイコンに加え、アクセシビリティ、デザイントークン、テーマ設定を扱います。
主な機能
- 01タイポグラフィの尺度と組み合わせ
- 02余白とサイズのシステム
- 03セマンティックカラーのトークン
- 04WCAG コントラストの指針
- 05アイコンのサイズとコンポーネント
- 06ダークモードとテーマ設定
活用シーン
- 01プロジェクトのデザイントークン定義
- 02アクセシブルなカラーパレットの作成
- 03可読性と視覚的階層の改善
- 04ビジュアルの一貫性の監査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ wshobson/ agents --skill visual-design-foundationsインストール後、Claude Code で/visual-design-foundationsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/color-systems.mdspacing-iconography.mdtypography-systems.md詳細
ビジュアルデザインの基礎
タイポグラフィ、カラー、スペーシング、アイコノグラフィーの基本要素を使って、一貫性がありアクセシブルなビジュアルシステムを構築します。
このスキルを使う場面
- 新しいプロジェクトのデザイントークンを確立するとき
- スペーシングとサイジングのシステムを作成または改善するとき
- 書体を選定して組み合わせるとき
- アクセシブルなカラーパレットを構築するとき
- アイコンシステムとビジュアルアセットを設計するとき
- ビジュアルヒエラルキーと可読性を改善するとき
- デザインのビジュアルの一貫性を監査するとき
- ダークモードやテーマを実装するとき
中核となるシステム
1. タイポグラフィスケール
モジュラースケール(比率ベースのサイジング):
:root {
--font-size-xs: 0.75rem; /* 12px */
--font-size-sm: 0.875rem; /* 14px */
--font-size-base: 1rem; /* 16px */
--font-size-lg: 1.125rem; /* 18px */
--font-size-xl: 1.25rem; /* 20px */
--font-size-2xl: 1.5rem; /* 24px */
--font-size-3xl: 1.875rem; /* 30px */
--font-size-4xl: 2.25rem; /* 36px */
--font-size-5xl: 3rem; /* 48px */
}
行間のガイドライン:
| テキストの種類 | 行間 |
|---|---|
| 見出し | 1.1 - 1.3 |
| 本文 | 1.5 - 1.7 |
| UI ラベル | 1.2 - 1.4 |
2. スペーシングシステム
8 ポイントグリッド(業界標準):
:root {
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 0.75rem; /* 12px */
--space-4: 1rem; /* 16px */
--space-5: 1.25rem; /* 20px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
--space-10: 2.5rem; /* 40px */
--space-12: 3rem; /* 48px */
--space-16: 4rem; /* 64px */
}
3. カラーシステム
セマンティックカラートークン:
:root {
/* Brand */
--color-primary: #2563eb;
--color-primary-hover: #1d4ed8;
--color-primary-active: #1e40af;
/* Semantic */
--color-success: #16a34a;
--color-warning: #ca8a04;
--color-error: #dc2626;
--color-info: #0891b2;
/* Neutral */
--color-gray-50: #f9fafb;
--color-gray-100: #f3f4f6;
--color-gray-200: #e5e7eb;
--color-gray-300: #d1d5db;
--color-gray-400: #9ca3af;
--color-gray-500: #6b7280;
--color-gray-600: #4b5563;
--color-gray-700: #374151;
--color-gray-800: #1f2937;
--color-gray-900: #111827;
}
クイックスタート: Tailwind でのデザイントークン
// tailwind.config.js
module.exports = {
theme: {
extend: {
fontFamily: {
sans: ["Inter", "system-ui", "sans-serif"],
mono: ["JetBrains Mono", "monospace"],
},
fontSize: {
xs: ["0.75rem", { lineHeight: "1rem" }],
sm: ["0.875rem", { lineHeight: "1.25rem" }],
base: ["1rem", { lineHeight: "1.5rem" }],
lg: ["1.125rem", { lineHeight: "1.75rem" }],
xl: ["1.25rem", { lineHeight: "1.75rem" }],
"2xl": ["1.5rem", { lineHeight: "2rem" }],
},
colors: {
brand: {
50: "#eff6ff",
500: "#3b82f6",
600: "#2563eb",
700: "#1d4ed8",
},
},
spacing: {
// Extends default with custom values
18: "4.5rem",
88: "22rem",
},
},
},
};
タイポグラフィのベストプラクティス
フォントの組み合わせ
安全な組み合わせ:
- 見出し: Inter / 本文: Inter(単一ファミリー)
- 見出し: Playfair Display / 本文: Source Sans Pro(コントラスト)
- 見出し: Space Grotesk / 本文: IBM Plex Sans(ジオメトリック)
レスポンシブタイポグラフィ
/* Fluid typography using clamp() */
h1 {
font-size: clamp(2rem, 5vw + 1rem, 3.5rem);
line-height: 1.1;
}
p {
font-size: clamp(1rem, 2vw + 0.5rem, 1.125rem);
line-height: 1.6;
max-width: 65ch; /* Optimal reading width */
}
フォントの読み込み
/* Prevent layout shift */
@font-face {
font-family: "Inter";
src: url("/fonts/Inter.woff2") format("woff2");
font-display: swap;
font-weight: 400 700;
}
カラー理論
コントラストの要件(WCAG)
| 要素 | 最小比率 |
|---|---|
| 本文 | 4.5:1 (AA) |
| 大きなテキスト(18px 以上) | 3:1 (AA) |
| UI コンポーネント | 3:1 (AA) |
| 強化 | 7:1 (AAA) |
ダークモードの戦略
:root {
--bg-primary: #ffffff;
--bg-secondary: #f9fafb;
--text-primary: #111827;
--text-secondary: #6b7280;
--border: #e5e7eb;
}
[data-theme="dark"] {
--bg-primary: #111827;
--bg-secondary: #1f2937;
--text-primary: #f9fafb;
--text-secondary: #9ca3af;
--border: #374151;
}
カラーのアクセシビリティ
// Check contrast programmatically
function getContrastRatio(foreground: string, background: string): number {
const getLuminance = (hex: string) => {
const rgb = hexToRgb(hex);
const [r, g, b] = rgb.map((c) => {
c = c / 255;
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
});
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
};
const l1 = getLuminance(foreground);
const l2 = getLuminance(background);
const lighter = Math.max(l1, l2);
const darker = Math.min(l1, l2);
return (lighter + 0.05) / (darker + 0.05);
}
スペーシングのガイドライン
コンポーネントのスペーシング
Card padding: 16-24px (--space-4 to --space-6)
Section gap: 32-64px (--space-8 to --space-16)
Form field gap: 16-24px (--space-4 to --space-6)
Button padding: 8-16px vertical, 16-24px horizontal
Icon-text gap: 8px (--space-2)
ビジュアルリズム
/* Consistent vertical rhythm */
.prose > * + * {
margin-top: var(--space-4);
}
.prose > h2 + * {
margin-top: var(--space-2);
}
.prose > * + h2 {
margin-top: var(--space-8);
}
アイコノグラフィー
アイコンサイジングシステム
:root {
--icon-xs: 12px;
--icon-sm: 16px;
--icon-md: 20px;
--icon-lg: 24px;
--icon-xl: 32px;
}
アイコンコンポーネント
interface IconProps {
name: string;
size?: "xs" | "sm" | "md" | "lg" | "xl";
className?: string;
}
const sizeMap = {
xs: 12,
sm: 16,
md: 20,
lg: 24,
xl: 32,
};
export function Icon({ name, size = "md", className }: IconProps) {
return (
<svg
width={sizeMap[size]}
height={sizeMap[size]}
className={cn("inline-block flex-shrink-0", className)}
aria-hidden="true"
>
<use href={`/icons.svg#${name}`} />
</svg>
);
}
ベストプラクティス
- 制約を設ける: 選択肢を限定して一貫性を保つ
- 決定を文書化する: 生きたスタイルガイドを作成する
- アクセシビリティをテストする: コントラスト、サイジング、タッチターゲットを検証する
- セマンティックトークンを使う: 見た目ではなく目的で命名する
- モバイルファーストで設計する: 制約から始め、複雑さを加える
- 垂直リズムを維持する: 一貫したスペーシングが調和を生む
- フォントウェイトを限定する: ファミリーごとに 2〜3 ウェイトで十分
よくある問題
- 一貫性のないスペーシング: 定義されたスケールを使っていない
- 不十分なコントラスト: WCAG の要件を満たしていない
- フォントの過多: ファミリーやウェイトが多すぎる
- マジックナンバー: トークンではなく任意の値を使っている
- 状態の欠落: ホバー、フォーカス、無効を忘れている
- ダークモードの計画がない: 後から対応するのは計画するより難しい
コメント
Markdown 対応