Web Design Patterns(ウェブデザインパターン) は何をしますか?
プロダクション向けインターフェースのためのCSS実装パターン集です。デザインの基礎と意思決定については ui-design を参照してください。このスキルはコードに焦点を当てています。
関連スキル:
ui-design(タイポグラフィ/カラー/スペーシング理論)、frontend-design(クリエイティブな美的感覚)
インストール
OpenClaw / Moltbot / Clawbot
npx clawhub@latest install web-design
レイアウトの原則
2次元レイアウトにはCSS Grid、1次元フローにはFlexboxを使用します。各コンテキストに適したツールを選びましょう。
| レイアウトの必要性 | ツール | 理由 |
|---|---|---|
| ページ全体の構造 | CSS Grid(grid-template-areas) | 名前付き領域、明示的な行/列制御 |
| ナビゲーションバー | Flexbox | 単一軸の整列、gapによるスペーシング |
| カードグリッド | Grid(auto-fill / auto-fit) | メディアクエリ不要のレスポンシブ対応 |
| 中央揃え | Grid(place-items: center) | 最も短く、信頼性の高い中央揃え |
| サイドバー+コンテンツ | Grid(grid-template-columns: 250px 1fr) | 固定サイドバーと比例サイズ調整 |
| 重なりレイヤー | Grid + grid-area: 1/1 | position: absolute を使わずに要素を重ねる |
空間構成(Spatial Composition)
予想通りのレイアウトから一歩踏み出しましょう。意図的な非対称性、重なり要素、グリッドを突き破るアクセントが視覚的な面白さを生み出します。重なり要素には position: absolute ではなく、グリッドのスタッキング(grid-area: 1/1)を使用します。ラグジュアリー/エディトリアル系の美学には広いネガティブスペースを、データリッチなインターフェースには制御された密度を選択してください。選択は意図的でなければなりません。
タイポグラフィ
タイポグラフィはデザインの個性の90%を担います。インターフェースの目的に合ったフォントを選びましょう。
| コンテキスト | 見出しフォントの方向性 | 本文フォントの方向性 | ペアリング例 |
|---|---|---|---|
| エディトリアル / 雑誌 | ハイコントラストセリフ | ニュートラルなヒューマニストサンセリフ | Playfair Display + Source Sans 3 |
| SaaSダッシュボード | ジオメトリックサンセリフ | 同系のウェイトのサンセリフ | DM Sans + DM Mono(データ用) |
| クリエイティブポートフォリオ | 表現力豊かなディスプレイ | クリーンで読みやすいサンセリフ | Syne + Outfit |
| Eコマースラグジュアリー | 細いモダンセリフ | エレガントなサンセリフ | Cormorant Garamond + Jost |
| デベロッパーツール | モノスペースディスプレイ | モノスペース本文 | JetBrains Mono + IBM Plex Mono |
タイプスケール
一貫した比率を使用します。1.25(長三度)のスケールはほとんどのインターフェースに適しています:text-xs 0.64rem、text-sm 0.8rem、text-base 1rem、text-lg 1.25rem、text-xl 1.563rem、text-2xl 1.953rem、text-3xl 2.441rem、text-4xl 3.052rem。本文テキストは 1rem(最小16px)、行高は本文 1.5、見出しは 1.1–1.2 に設定します。行長は 60–75ch に制限します。
カラー
パレットの構築
すべてのパレットには5つの機能的役割が必要です:
| 役割 | 目的 | 使用例 |
|---|---|---|
| プライマリ | ブランドアイデンティティ、主要なアクション | ボタン、リンク、アクティブ状態 |
| ニュートラル | テキスト、ボーダー、背景 | 本文、カード、区切り線 |
| アクセント | セカンダリアクション、ハイライト | タグ、バッジ、セカンダリボタン |
| 成功 / 警告 / エラー | セマンティックフィードバック | トースト、フォームバリデーション、ステータス |
| サーフェス | レイヤー化された背景 | ページ上のカード、オーバーレイ上のモーダル |
コントラストと深み
影だけでなく、サーフェスのレイヤリングによって深みを生み出します:
:root {
--surface-0: hsl(220 15% 8%); /* ページ背景 */
--surface-1: hsl(220 15% 12%); /* カード */
--surface-2: hsl(220 15% 16%); /* 浮き上がった要素 */
--surface-3: hsl(220 15% 20%); /* ポップオーバー / モーダル */
}
知覚的に均一なカラー操作にはHSLまたはOKLCHを使用します。支配的な色とシャープなアクセントの組み合わせは、均等に分散されたパレットよりも効果的です。必ずWCAGコントラストを確認してください:標準テキストは4.5:1、大きなテキストは3:1。
スペーシング
一貫したスペーシングはリズムを生み出します。8pxベースユニット(密度の高いUIでは4px)を使用します:
| トークン | 値 | 使用例 |
|---|---|---|
--space-1 | 0.25rem (4px) | インラインアイコンのギャップ、タイトなパディング |
--space-2 | 0.5rem (8px) | 入力フィールドのパディング、コンパクトなリスト |
--space-3 | 0.75rem (12px) | ボタンのパディング、カードの内部スペーシング |
--space-4 | 1rem (16px) | デフォルトの要素間スペーシング |
--space-6 | 1.5rem (24px) | セクションのパディング、カード間のギャップ |
--space-8 | 2rem (32px) | セクションの分離 |
--space-12 | 3rem (48px) | 主要なセクションブレーク |
--space-16 | 4rem (64px) | ページレベルの垂直リズム |
スペーシングは一貫して適用します:子要素にマージンを使う代わりに、Grid/Flexboxコンテナに gap を使用します。これによりマージンの相殺バグがなくなり、レスポンシブ調整が簡素化されます。
視覚的階層
サイズ、太さ、色、スペースの意図的なコントラストによって視線を誘導します。
階層テクニック
| テクニック | 方法 | 効果 |
|---|---|---|
| サイズのコントラスト | ヒーロー見出しを本文の3~4倍に | 即座に視線を集める焦点 |
| 太さのコントラスト | 太字の見出し + 標準の本文 | スキャン容易性 |
| 色のコントラスト | プライマリテキスト vs ミュートされたセカンダリ | 情報の階層化 |
| 空間グルーピング | グループ内はタイト、グループ間は広く | ゲシュタルトの近接性 |
| エレベーション | 影 / サーフェスレイヤー | インタラクティブなアフォーダンス |
| 余白による分離 | キー要素の周りに空白を配置 | 不在による強調 |
実践パターン — カードの階層
カード内で階層をレイヤー化します:アイブロウ(xs、大文字、ミュート)→ タイトル(xl、セミボールド)→ 本文(base、セカンダリカラー、行高1.6)→ アクション(margin-top で離して配置)。サーフェスカラーで区切りを付け、スペーシングトークンから一貫したパディングを使用します。
レスポンシブデザイン
ブレークポイント戦略
| ブレークポイント | 対象 | アプローチ |
|---|---|---|
< 640px | モバイル | シングルカラム、スタックナビゲーション、タッチターゲット ≥ 44px |
640–1024px | タブレット | 二段組オプション、折りたたみ可能なサイドバー |
1024–1440px | デスクトップ | フルレイアウト、ホバーインタラクション有効 |
> 1440px | ワイド | 最大幅コンテナ(1280px)、超広行長を防止 |
流体テクニック
可能な限り、固定ブレークポイントよりも流体サイズ指定を優先します:
/* 流体タイポグラフィ — 640pxから1440pxのビューポートでスケーリング */
h1 { font-size: clamp(2rem, 1.5rem + 2.5vw, 3.5rem); }
/* 流体スペーシング */
section { padding-block: clamp(2rem, 1rem + 4vw, 6rem); }
/* 内在的グリッド — メディアクエリ不要 */
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); gap: var(--space-6); }
コンポーネントのレイアウトがビューポートではなくコンテナに応答する必要がある場合は、コンテナクエリ(@container)を使用します。
アクセシビリティ
アクセシビリティはオプションではありません。最初から組み込みましょう。
| 要件 | 実装 | 標準 |
|---|---|---|
| カラーコントラスト | 標準テキスト4.5:1、大きなテキスト/UIは3:1 | WCAG 2.1 AA |
| キーボードナビゲーション | すべてのインタラクティブ要素がフォーカス可能かつ操作可能 | WCAG 2.1.1 |
| フォーカスインジケーター | 可視の :focus-visible リング、2px以上オフセット | WCAG 2.4.7 |
| セマンティックHTML | <button>、<nav>、<main>、<article> などを使用 | WCAG 1.3.1 |
| 代替テキスト | 情報画像には説明的、装飾画像には alt="" | WCAG 1.1.1 |
| モーションの安全性 | prefers-reduced-motion を尊重 | WCAG 2.3.3 |
| タッチターゲット | インタラクティブ領域は最小44×44px | WCAG 2.5.8 |
| 必要な場合のARIA | aria-label、aria-live、role はネイティブセマンティクスが不十分な場合のみ | WCAG 4.1.2 |
/* 堅牢なフォーカスインジケーター */
:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
/* モーション設定を尊重 */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
コンポーネント設計
適切に設計されたコンポーネントの構造
すべてのUIコンポーネントには、明確な状態、一貫したスペーシング、予測可能な振る舞いが必要です:
| 状態 | ビジュアル処理 | 例 |
|---|---|---|
| デフォルト | 基本スタイル | 通常時のボタン |
| ホバー | 微妙な変化 — 背景、影、またはスケール | background が5〜10%明るく |
| アクティブ / 押下時 | 圧縮された感覚 — 影を縮小、少し内側に | transform: scale(0.98) |
| フォーカス | 高視認性リング、アウトラインは削除しない | :focus-visible リング |
| 無効 | 透明度を下げ、cursor: not-allowed | opacity: 0.5 |
| ローディング | スピナーまたはスケルトン、インタラクション無効 | ラベルをインラインスピナーに置き換え |
デザイントークンアーキテクチャ
保守性のためにトークンを3つのレイヤーに構造化します:
/* レイヤー1: プリミティブ値 */
--blue-500: oklch(0.55 0.2 250);
--gray-100: oklch(0.95 0.005 250);
--radius-md: 0.5rem;
/* レイヤー2: セマンティックエイリアス */
--color-primary: var(--blue-500);
--color-surface: var(--gray-100);
--radius-button: var(--radius-md);
/* レイヤー3: コンポーネント固有 */
--btn-bg: var(--color-primary);
--btn-radius: var(--radius-button);
--btn-padding: var(--space-2) var(--space-4);
この3層アプローチにより、レイヤー2を再マッピングするだけでテーマを切り替えることができ、コンポーネントに影響を与えません。
インタラクションパターン
モーションとアニメーション
モーションは状態変化を伝えるために使用し、装飾のために使用してはいけません。インパクトの大きい瞬間に焦点を当てます:
| インタラクション | 継続時間 | イージング | 目的 |
|---|---|---|---|
| ボタンホバー | 150ms | ease-out | インタラクションを認識 |
| モーダル開く | 250ms | ease-out | 注意を引く |
| モーダル閉じる | 200ms | ease-in | 素早くしまう |
| ページ遷移 | 300ms | ease-in-out | 空間コンテキストを維持 |
| 段階的表示 | アイテムごとに50〜80ms遅延 | ease-out | 順次コンテンツ読み込み |
| マイクロフィードバック | 100ms | ease-out | トグル、チェックボックス、スイッチ |
/* 段階的に出現するアニメーション */
.stagger-item {
opacity: 0;
translate: 0 1rem;
animation: reveal 0.5s ease-out forwards;
}
.stagger-item:nth-child(1) { animation-delay: 0ms; }
.stagger-item:nth-child(2) { animation-delay: 60ms; }
.stagger-item:nth-child(3) { animation-delay: 120ms; }
@keyframes reveal {
to { opacity: 1; translate: 0 0; }
}
スクロール駆動エフェクト
JavaScriptを使用せずにパララックスや表示エフェクトには、ネイティブの animation-timeline: scroll()(@supports でガード)を使用します。機能検出でラップして、グレースフルデグラデーションを実現します。
デザイン品質チェックリスト
リリース前に、以下の基準に対して検証します:
- タイポグラフィ: 意図的なフォントペアリング、一貫したスケール、読みやすい行長
- カラー: まとまりのあるパレット、WCAGコントラストを満たしている、セマンティックフィードバックカラーが定義されている
- スペーシング: スペーシングトークンを使用した一貫したリズム、アドホックなピクセル値がない
- 階層: 明確な視覚フロー — 視線が意図された読み順に沿う
- レスポンシブ: モバイル、タブレット、デスクトップでテスト済み、水平方向のオーバーフローがない
- アクセシビリティ: キーボード操作可能、フォーカス可視、スクリーンリーダーテスト済み、モーションセーフ
- 状態: すべてのインタラクティブ要素にホバー、アクティブ、フォーカス、無効、ローディング状態がある
- 個性: デザインに明確な視点がある — 汎用テンプレートの美学ではない
- パフォーマンス: 画像最適化、フォントサブセット化、アニメーションはGPUアクセラレーション(
transform、opacity) - ダークモード: サポートする場合、サーフェスは反転色ではなく、明るさのレイヤー化を使用