ソフトウェアエンジニアのためのデザイン原則
より良いソフトウェアを構築するためのデザイン基礎を学ぶ。タイポグラフィ、色彩理論、余白、アニメーション、ArcからStripeまでの16事例。
2026年2月9日更新
2026年2月アップデート: 2つの新セクションを追加しました—インタラクションパターン(Framer、Flighty、Halide、Warp、Bear、Craft、Superhumanの研究から導き出した8つのパラダイム)とAIインターフェースパターン(Perplexityから学んだ引用優先デザイン、ストリーミングフェーズ、エラー透明性)。Webパターンを2026年版に更新し、アンカーポジショニング、スクロール駆動アニメーション、@starting-styleを追加しました。アクセシビリティについてはWCAG 2.2のISO標準化を反映しています。16の優れたプロダクトの詳細な分析はデザインスタディをご覧ください。
私はソフトウェアを開発しながら何年もデザインを研究してきました。Dieter Ramsのような巨匠たちの原則を吸収し、Linear、Stripe、Raycastといったプロダクトのインターフェースを分析してきました。このガイドは、自分のソフトウェアの見た目と使い心地に本気で向き合い始めたときに「こんなリファレンスがあれば」と思っていたものを、包括的にまとめたものです。
デザインは装飾ではありません。コミュニケーションです。すべてのピクセルが機能、階層、意味を伝えています。アマチュアに感じるソフトウェアとプロフェッショナルに感じるソフトウェアの違いは、これらの原則を理解し、一貫して適用できるかどうかにあります。
このガイドは、すでにコードが書けることを前提としています。ここで学ぶのは「見る力」です—なぜあるインターフェースは自然に感じられ、別のインターフェースは混沌として感じるのか。そしてさらに重要なのは、前者をどう作るかということです。
目次
Part 1:基礎
Part 2:インタラクションと AI
Part 3:デザイン哲学
Part 4:実装
Part 5:リファレンス
Gestalt 心理学
「全体は部分の総和とは異なるものである」— Kurt Koffka
Gestalt 心理学は1920年代のドイツで生まれた理論で、人間が視覚情報をどのように知覚するかを説明します。脳は個々のピクセルをそのまま見ているのではなく、要素を意味のあるパターンに整理しています。これらの原則を理解することで、ユーザーがインターフェースをどう知覚するかをコントロールできます。
近接の法則
近くにある要素はグループとして知覚されます。
これは UI デザインにおいて最も強力な Gestalt 原則です。スペースは他のどの視覚的要素よりも、要素間の関係性を伝えます。
WRONG (equal spacing = no grouping):
┌─────────────────┐
│ Label │
│ │
│ Input Field │
│ │
│ Label │
│ │
│ Input Field │
└─────────────────┘
RIGHT (unequal spacing = clear groups):
┌─────────────────┐
│ Label │
│ Input Field │ ← Tight (4px) - related
│ │
│ │ ← Wide (24px) - separating groups
│ Label │
│ Input Field │ ← Tight (4px) - related
└─────────────────┘
CSS の実装:
.form-group {
margin-bottom: 24px; /* Between groups: wide */
}
.form-group label {
margin-bottom: 4px; /* Label to input: tight */
display: block;
}
SwiftUI の実装:
VStack(alignment: .leading, spacing: 4) { // Tight within group
Text("Email")
.font(.caption)
.foregroundStyle(.secondary)
TextField("[email protected]", text: $email)
.textFieldStyle(.roundedBorder)
}
.padding(.bottom, 24) // Wide between groups
類似の法則
視覚的な特徴を共有する要素は、関連があるように見えます。
要素の見た目が同じであれば、ユーザーはそれらが同じ機能を持つと推測します。デザインシステムがボタンスタイル、カードの扱い、タイポグラフィを統一する理由はここにあります。
Example Navigation:
┌───────────────────────────────────┐
│ [Dashboard] [Projects] [Settings] │ ← Same style = same function
│ │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Card │ │Card │ │Card │ │ ← Same style = same content type
│ └─────┘ └─────┘ └─────┘ │
│ │
│ [+ New Project] │ ← Different style = different function
└───────────────────────────────────┘
図と地の法則
コンテンツは背景から明確に区別される必要があります。
脳は「図」(注目すべきもの)と「地」(背景)を区別する必要があります。図と地の関係が不明確だと、視覚的な混乱が生じます。
テクニック: - コントラスト(暗い地に明るい図、またはその逆) - シャドウ(図を地から浮き上がらせる) - ボーダー(図の輪郭を区切る) - ブラー(背景をぼかし、図を鮮明にする)
/* Strong figure-ground relationship */
.card {
background: var(--color-surface); /* Figure */
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1); /* Elevation */
}
.modal-overlay {
background: rgba(0, 0, 0, 0.5); /* Dim ground */
backdrop-filter: blur(4px); /* Blur ground */
}
共通領域の法則
境界線の中にある要素は、グループとして知覚されます。
要素を視覚的なコンテナ(カード、ボックス、枠線で囲まれた領域)で囲むことで、それらが一つのまとまりであることを示します。
連続の法則
視線はパス、線、曲線に沿って流れます。
整列と視覚的なフローを活用して、インターフェース内でユーザーの注意を導きます。
CONTINUITY IN ALIGNMENT:
┌────────────────────────────────┐
│ Logo [Nav] [Nav] [Nav] │ ← Aligned on horizontal axis
├────────────────────────────────┤
│ │
│ Headline │
│ ───────────────────────────── │ ← Eye follows left edge
│ Paragraph text continues │
│ along the same left edge │
│ │
│ [Primary Action] │ ← Still on the left edge
└────────────────────────────────┘
閉合の法則
脳は不完全な形を補完します。
ユーザーはすべてのピクセルが描かれていなくても、見慣れた形を頭の中で補完します。これにより、よりミニマルで洗練されたデザインが可能になります。
/* Horizontal scroll with partial card (closure) */
.card-carousel {
display: flex;
gap: 16px;
overflow-x: auto;
padding-right: 48px; /* Show partial card = scroll hint */
}
.card-carousel .card {
flex: 0 0 280px; /* Fixed width, partial visible */
}
Gestalt クイックリファレンス
| 原則 | ルール | 主な用途 |
|---|---|---|
| 近接 | 関連するもの=近く、無関係なもの=遠く | フォームフィールド、コンテンツセクション |
| 類似 | 同じ見た目=同じ機能 | ボタン、カード、ナビゲーション |
| 図と地 | レイヤーの明確な分離 | カード、モーダル、オーバーレイ |
| 共通領域 | 境界がコンテンツをグループ化する | 設定セクション、ユーザーカード |
| 連続 | 線と整列に沿って流れる | タイムライン、読みの流れ |
| 閉合 | 脳が形を補完する | アイコン、スクロールヒント、スケルトン |
タイポグラフィ
「タイポグラフィとは、人間の言語に永続的な視覚的形式を与える技術である」— Robert Bringhurst
タイポグラフィはインターフェースデザインの基盤です。テキストは機能、階層、ブランドを伝えます。タイポグラフィが悪ければインターフェースは使いにくくなり、優れたタイポグラフィは意識されることなく—ただ自然に機能します。
タイプスケール
一貫したスケールは視覚的な調和を生み出します。数学的な比率を使用します。
1.25スケール(UI に推奨):
:root {
/* Base: 16px (1rem) */
--text-xs: 0.64rem; /* 10.24px - use sparingly */
--text-sm: 0.8rem; /* 12.8px - captions, labels */
--text-base: 1rem; /* 16px - body text */
--text-lg: 1.25rem; /* 20px - lead text */
--text-xl: 1.563rem; /* 25px - h4 */
--text-2xl: 1.953rem; /* 31.25px - h3 */
--text-3xl: 2.441rem; /* 39px - h2 */
--text-4xl: 3.052rem; /* 48.8px - h1 */
}
行間(レディング)
行間は可読性に大きく影響します。コンテンツの種類によって適切な行間は異なります。
| コンテンツタイプ | 行間 | 理由 |
|---|---|---|
| 見出し | 1.1 - 1.2 | タイトで太く、短い |
| UI テキスト | 1.3 - 1.4 | ラベル、ボタン |
| 本文 | 1.5 - 1.7 | 読みやすい段落 |
| 長文 | 1.7 - 2.0 | 記事、ドキュメント |
行長(メジャー)
最適な行長は目の疲れを防ぎ、読解力を向上させます。
- 最適: 1行あたり45〜75文字
- 目標: 50〜65文字
- 絶対上限: 85文字
p {
max-width: 65ch; /* ch unit = width of '0' character */
}
.article-body {
max-width: 70ch;
margin: 0 auto;
}
フォント選択
まずシステムフォントを使いましょう。 読み込みが瞬時で、プラットフォームに合致し、スクリーン表示に最適化されています。
:root {
--font-sans: system-ui, -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
--font-mono: ui-monospace, 'SF Mono', 'Cascadia Code',
'JetBrains Mono', Consolas, monospace;
}
カスタムフォントを使う場合: - ブランドの差別化(マーケティングサイト) - エディトリアル・出版的な雰囲気 - システムフォントでは実現できない特定のデザイン意図
フォントウェイトによる階層
サイズだけでなく、ウェイトで階層を確立します。
h1 { font-weight: 700; } /* Bold */
h2 { font-weight: 600; } /* Semibold */
h3 { font-weight: 600; } /* Semibold */
.lead { font-weight: 500; } /* Medium */
p { font-weight: 400; } /* Regular */
.meta { font-weight: 400; color: var(--text-muted); }
タイポグラフィ クイックリファレンス
| プロパティ | 本文 | 見出し | UI ラベル |
|---|---|---|---|
| サイズ | 16-18px | 24-48px | 12-14px |
| ウェイト | 400 | 600-700 | 500 |
| 行間 | 1.5-1.7 | 1.1-1.2 | 1.3-1.4 |
| 行長 | 45-75ch | N/A | N/A |
| 揃え | 左揃え | 中央揃え可 | 左揃え |
色彩理論
「色彩は魂に直接影響を与える力である」— Wassily Kandinsky
色は言葉よりも速く情報を伝えます。ムードを確立し、注意を導き、意味を示し、ブランド認知を構築します。
60-30-10 ルール
バランスの取れたインターフェースのための、最も信頼性の高い色の配分方法です。
┌──────────────────────────────────────────┐
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ 60% - Dominant (Background)
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░░░░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░│ 30% - Secondary (Cards, sections)
│░░░░░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░│
│░░░░░▓▓▓▓▓▓▓▓▓▓▓▓██████▓▓▓▓▓▓▓▓▓▓░░░░░░░░│ 10% - Accent (Buttons, links)
└──────────────────────────────────────────┘
カラーパレットの構築
すべてのインターフェースに必要なセマンティックカラーは以下の通りです:
:root {
/* Brand */
--color-primary: hsl(220, 80%, 50%);
--color-primary-hover: hsl(220, 80%, 45%);
/* Semantic */
--color-success: hsl(142, 76%, 36%); /* Green - positive */
--color-warning: hsl(38, 92%, 50%); /* Amber - caution */
--color-error: hsl(0, 84%, 60%); /* Red - danger */
/* Neutrals */
--color-background: hsl(0, 0%, 100%);
--color-surface: hsl(220, 14%, 96%);
--color-border: hsl(220, 13%, 91%);
/* Text */
--color-text: hsl(220, 13%, 13%);
--color-text-secondary: hsl(220, 9%, 46%);
--color-text-muted: hsl(220, 9%, 64%);
}
色彩心理学
| 色 | 心理的効果 | UI での用途 |
|---|---|---|
| 青 | 信頼、安定、穏やかさ | 金融、テック、コーポレート |
| 緑 | 成長、自然、成功 | ヘルスケア、エコ、ポジティブな状態 |
| 赤 | エネルギー、緊急性、危険 | アラート、セール、エラー |
| オレンジ | 温かさ、熱意 | CTA、遊び心のあるブランド |
| 黄 | 楽観、注意 | 警告、ハイライト |
| 紫 | 高級感、創造性 | プレミアム製品 |
ダークモードファースト デザイン(Vercel)
Vercel はダークモードを先にデザインし、そこからライトモードを導出します。このアプローチにより、ダークモードが後付けではなく主要な考慮事項となるため、より優れたダークインターフェースが生まれます。
/* Design dark first, derive light */
:root {
/* Dark mode defaults */
--color-background: hsl(0, 0%, 0%);
--color-surface: hsl(0, 0%, 7%);
--color-border: hsl(0, 0%, 15%);
--color-text: hsl(0, 0%, 93%);
--color-text-secondary: hsl(0, 0%, 63%);
}
@media (prefers-color-scheme: light) {
:root {
--color-background: hsl(0, 0%, 100%);
--color-surface: hsl(0, 0%, 97%);
--color-border: hsl(0, 0%, 89%);
--color-text: hsl(0, 0%, 9%);
--color-text-secondary: hsl(0, 0%, 40%);
}
}
使用すべき場面: 開発者ツール、メディアアプリ、ダッシュボード—ユーザーが長時間操作する場面で、ダークモードが目の疲れを軽減します。
アクセシビリティのコントラスト
| レベル | 通常テキスト | 大きなテキスト | UI コンポーネント |
|---|---|---|---|
| AA | 4.5:1 | 3:1 | 3:1 |
| AAA | 7:1 | 4.5:1 | N/A |
WCAG 2.2 は2025年10月に ISO 標準(ISO/IEC 40500:2025)となり、フォーカスの可視性、冗長入力、アクセシブルな認証に関する基準が追加されました。主な追加事項:フォーカスインジケーターが他のコンテンツによって完全に隠されてはならない(2.4.11)、認証が認知機能テストのみに依存してはならない(3.3.8)。
ツール: WebAIM Contrast Checker、Chrome DevTools カラーピッカー
ビジュアル階層
「デザインはブランドの無言の大使である。」— Paul Rand
ビジュアル階層は、ユーザーが最初に何を見て、次に何を見て、その次に何を見るかをコントロールします。明確な階層がなければ、ユーザーは情報を探すために努力しなければなりません。階層があれば、インターフェースは自然で楽に感じられます。
階層の6つのツール
1. サイズ — 大きな要素が最初に注意を引きます
.hero-title { font-size: 3rem; } /* Dominant */
.section-title { font-size: 1.5rem; } /* Secondary */
.body-text { font-size: 1rem; } /* Baseline */
2. ウェイト — 太字は前面に飛び出し、細字は後退します
h1 { font-weight: 700; }
.lead { font-weight: 500; }
p { font-weight: 400; }
3. 色とコントラスト — 高コントラスト=注目
.title { color: var(--color-text); } /* Near black */
.meta { color: var(--color-text-muted); } /* Gray */
4. 配置 — 重要なポジションが意味を持ちます
F-PATTERN (content pages): Z-PATTERN (landing pages):
████████████████████████ 1 ──────────────────► 2
████████ ↘
████ ↘
██ ↘
3 ──────────────────► 4
5. ホワイトスペース — 孤立が重要性を生み出します
.hero { padding: 120px 48px; } /* Generous space */
.data-table { padding: 12px; } /* Dense content */
6. 奥行きとエレベーション — 前面に浮き出る要素が注意を引きつけます
:root {
--shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
--shadow-md: 0 4px 6px rgba(0,0,0,0.1);
--shadow-lg: 0 10px 15px rgba(0,0,0,0.1);
}
.card { box-shadow: var(--shadow-sm); }
.card:hover { box-shadow: var(--shadow-md); }
.modal { box-shadow: var(--shadow-lg); }
実践パターン
コラボレーションプレゼンス(Figma): 複数のユーザーカーソルに名前ラベル、選択ハイライト、コンポーネントのアウトラインが表示され、生きたドキュメントを作り出します。各コラボレーターの色は区別されていますが、同等のウェイトで表示されます。どのカーソルも他より「目立つ」ことはありません。
環境ステータスインジケーター(Vercel): デプロイステータスは、押しつけがましいアラートではなく、控えめで常時表示されるインジケーターを使用します。画面上部の細いカラーバーが状態(ビルド中、デプロイ済み、失敗)を伝え、ワークフローを中断しません。
現実世界のデザインアナロジー(Flighty): フライト進行状況の可視化は、物理的な航空計器を模しています。高度曲線、速度インジケーター、ゲートマップは、抽象的なプログレスバーの代わりに馴染みのあるビジュアルメタファーを使用しています。
目を細めるテスト
デザインを見て目を細めてください。それでも階層が見えますか?見えるなら、強い階層です。
スペーシングとリズム
「ホワイトスペースは空気のようなもの。デザインが呼吸するために必要なのです。」— Wojciech Zieliński
スペーシングはデザインの見えない構造です。一貫したスペーシングはビジュアルリズムを生み出します。それは、要素が一つのまとまったシステムに属しているという感覚です。
8pxグリッド
8pxグリッドが業界標準である理由は以下の通りです: - 均等に分割できます(8、16、24、32、40、48…) - 一般的な画面密度に対応します(1x、1.5x、2x、3x) - 計算不要で一貫したリズムを作り出します
:root {
--space-1: 4px; /* Tight: icon gaps */
--space-2: 8px; /* Compact: inline elements */
--space-3: 12px; /* Snug: form fields */
--space-4: 16px; /* Default: most gaps */
--space-6: 24px; /* Spacious: card padding */
--space-8: 32px; /* Section gaps */
--space-12: 48px; /* Major sections */
--space-16: 64px; /* Page sections */
--space-20: 80px; /* Hero spacing */
}
内部スペーシングと外部スペーシング
内部(padding): 要素の内側のスペース 外部(margin): 要素間のスペース
ルール: 関連するグループ内では、内部スペーシングは通常、外部スペーシングより大きくする必要があります。
.card {
padding: 24px; /* Internal: spacious */
margin-bottom: 16px; /* External: less than padding */
}
コンポーネントのスペーシングパターン
カード:
.card { padding: 24px; border-radius: 12px; }
.card-header { margin-bottom: 16px; }
.card-title { margin-bottom: 4px; } /* Tight to subtitle */
ボタン:
.btn { padding: 12px 24px; border-radius: 8px; }
.btn--sm { padding: 8px 16px; }
.btn--lg { padding: 16px 32px; }
.btn-group { display: flex; gap: 12px; }
フォーム:
.form-row { margin-bottom: 24px; }
.form-label { margin-bottom: 4px; }
.form-help { margin-top: 4px; }
.form-actions { margin-top: 32px; display: flex; gap: 12px; }
スペーシングクイックリファレンス
| コンテキスト | 推奨スペーシング |
|---|---|
| アイコンとテキストの間 | 4-8px |
| ラベルと入力フィールドの間 | 4px |
| フォームグループ間 | 24px |
| カードのpadding | 20-24px |
| カード間のgap | 16-24px |
| セクションpadding(モバイル) | 48-64px |
| セクションpadding(デスクトップ) | 80-96px |
| ボタンpadding(水平/垂直) | 24px / 12px |
アニメーションの原則
「アニメーションとは、動く絵を描く技術ではなく、描かれた動きの技術である。」— Norman McLaren
アニメーションはインターフェースに命を吹き込みます。うまく使えば、注意を誘導し、状態を伝え、感情的なつながりを生み出します。うまくいかなければ、ユーザーを苛立たせ、気を散らせます。
核となる原則
アニメーションは装飾ではなく、必然であるべきです。
良いアニメーション: 1. 静的なデザインでは伝えられないことを伝えます 2. 関係性を示すことで認知負荷を軽減します 3. 自然で予想通りに感じられます 4. 意識的な認識から消えます
悪いアニメーション: 1. 「かっこいいから」という理由だけで存在します 2. ユーザーの操作を遅くします 3. それ自体に注意を向けさせます 4. 不安や苛立ちを生み出します
UIにおける主要原則
1. 予備動作(Anticipation) — これから起こることにユーザーを備えさせます。
.button {
transition: transform 0.1s ease-out;
}
.button:active {
transform: scale(0.97); /* Slight press before action */
}
2. フォロースルー(Follow-Through) — 動きをバネのように自然に完了させます。
.panel {
transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
withAnimation(.spring(response: 0.4, dampingFraction: 0.7)) {
isOpen = true
}
3. イーズイン・イーズアウト(Ease-In, Ease-Out) — 自然界では何も一定速度で動きません。
| カーブ | 使用場面 | 特徴 |
|---|---|---|
ease-out |
要素の登場時 | 素早い開始、穏やかな停止 |
ease-in |
要素の退出時 | 穏やかな開始、素早い退出 |
ease-in-out |
状態変化時 | 全体を通してスムーズ |
linear |
ローディングインジケーター | 連続的、機械的 |
4. ステージング(Staging) — 重要なものに注意を向けさせます。グループとして演出される場合を除き、一度に動くのは一つだけにすべきです。
5. スタガリング(Staggering) — 要素は一斉にではなく、順番に登場すべきです。
.list-item {
animation: fadeSlideIn 0.3s ease-out both;
}
.list-item:nth-child(1) { animation-delay: 0ms; }
.list-item:nth-child(2) { animation-delay: 50ms; }
.list-item:nth-child(3) { animation-delay: 100ms; }
.list-item:nth-child(4) { animation-delay: 150ms; }
@keyframes fadeSlideIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
タイミングガイドライン
| 時間 | 使用場面 | 印象 |
|---|---|---|
| 50-100ms | マイクロインタラクション(ホバー、プレス) | 即座のフィードバック |
| 150-200ms | シンプルな状態変化(トグル、選択) | キビキビ |
| 250-350ms | 中程度のトランジション(パネルスライド、カードフリップ) | スムーズ |
| 400-500ms | 大きな動き(ページ遷移、モーダル) | 意図的 |
パフォーマンス:ゴールデンルール
アニメーションは transform と opacity のみに適用しましょう — これらはGPUアクセラレーションが効き、レイアウトの再計算を引き起こしません。
/* BAD: Animating layout */
.panel { transition: left 0.3s, width 0.3s; }
/* GOOD: Using transform */
.panel { transition: transform 0.3s; }
アニメーションすべきでない場面
-
ユーザーが
prefers-reduced-motionを有効にしている場合css @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } } -
アニメーションが情報を追加しない場合 — 不必要なスピナー、バウンスする要素
- ユーザーが急いでいる場合 — エラー状態、フォームバリデーション、検索結果
- アニメーションが繰り返し操作を遅くする場合 — キーボードショートカットはアニメーションをバイパスすべきです
- データがすでに読み込まれている場合 — Bearはコンテンツをプリロードすることでローディング状態をゼロにし、アプリを瞬時に感じさせます。プリロードできるなら、スケルトンやスピナーは省略しましょう。
// Bear's approach: preload so no loading state is needed
struct NoteListView: View {
@Query var notes: [Note] // SwiftData loads from disk instantly
// No loading state, no skeleton, no spinner — data is always there
var body: some View {
List(notes) { note in
NoteRow(note: note)
}
}
}
アニメーションクイックリファレンス
:root {
/* Durations */
--duration-instant: 0.1s;
--duration-fast: 0.15s;
--duration-normal: 0.25s;
--duration-slow: 0.4s;
/* Easings */
--ease-out: cubic-bezier(0.0, 0.0, 0.58, 1.0);
--ease-in: cubic-bezier(0.42, 0.0, 1.0, 1.0);
--ease-in-out: cubic-bezier(0.42, 0.0, 0.58, 1.0);
--ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
}
インタラクションパターン
「最高のインターフェースとは、インターフェースが存在しないことだ。」 — Golden Krishna
インタラクションパターンは、ユーザーがプロダクトをどのように操作し、ナビゲートし、理解するかを定義します。これらのパターンは、優れたインタラクションを実現しているプロダクトの研究から抽出されたものです。
直接操作(Framer)
抽象的な概念を直感的に操作できるようにします。Framer は CSS のブレークポイント(抽象的な数値)をドラッグ可能なハンドルに変換します。ユーザーはレイアウトがリアルタイムで適応する様子を確認できます。
/* Breakpoint handle styling */
.breakpoint-handle {
position: absolute;
top: 0;
bottom: 0;
width: 4px;
background: var(--accent);
cursor: col-resize;
opacity: 0.6;
transition: opacity 0.15s ease;
}
.breakpoint-handle:hover,
.breakpoint-handle:active {
opacity: 1;
width: 6px;
}
使いどころ: 結果が視覚的に確認できるあらゆる設定—ドラッグによるリサイズ、カラーピッカー、タイムラインのスクラブなど。
コンテキストアウェアインターフェース(Flighty、Figma)
その瞬間に関連する情報だけを表示します。Flighty はフライト追跡に15の異なる状態を使用しています。Figma のプロパティパネルは、選択したオブジェクトに応じて完全に変化します。
| フェーズ(Flighty) | ユーザーに表示される内容 |
|---|---|
| 24時間前 | 確認コード、ターミナル情報 |
| 空港到着時 | ゲート番号、搭乗時刻 |
| 飛行中 | 残り時間、進捗、到着予定時刻 |
| 着陸時 | 乗り継ぎゲート、移動経路 |
enum ContextState: CaseIterable {
case farOut, dayBefore, headToAirport, atAirport
case atGate, boarding, inFlight, landed, connection
static func current(for flight: Flight, context: UserContext) -> ContextState {
// Factor in: time, location, flight status
// Return the single most relevant state
}
}
アンチパターン: すべてのコントロールを表示し、関連のないものをグレーアウトすること。これは視覚的なノイズを生み出します。
インテリジェントアクティベーション(Halide)
ツールはコンテキストを検知して自動的に起動するべきです。Halide のフォーカスルーペは、フォーカスのドラッグ時に表示され、リリース時に消えます。トグルボタンは不要です。
struct IntelligentlyActivated<Content: View>: ViewModifier {
let isInteracting: Bool
@State private var isVisible = false
func body(content: Content) -> some View {
content
.opacity(isVisible ? 1 : 0)
.scaleEffect(isVisible ? 1 : 0.95)
.animation(.easeInOut(duration: 0.2), value: isVisible)
.onChange(of: isInteracting) { _, newValue in
if newValue {
withAnimation { isVisible = true }
} else {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
if !isInteracting { isVisible = false }
}
}
}
}
}
デュアルモードデザイン(Halide、Warp)
モード切り替えは、単に要素をトグルするのではなく、UI を根本的に変化させるべきです。Halide のオートモードとマニュアルモードは、まったく異なるインターフェースです。Warp は4つの入力方法(タイピング、パレット、AI、マウス)を通じて CLI と GUI を橋渡しし、ユーザーを1つのパラダイムに強制しません。
構造化コンテンツ(Warp、Bear、Craft)
従来は非構造的だったコンテンツに構造を加えます。Warp はターミナル出力を個別のブロックに変換し、コピー、共有、再実行を可能にします。Bear はノートを書きながらインラインで整理できます(#tag/subtag)。Craft はあらゆるブロックをページに変換でき、構造はあらかじめ定義された階層からではなく、使用を通じて自然に生まれます。
プログレッシブトレーニング(Superhuman)
繰り返しの接触を通じて、ユーザーに効率的な操作方法を教えます。Superhuman の Cmd+K パレットは、検索結果の横に常にキーボードショートカットを表示します。操作するたびにマイクロレッスンとなります。
/* Always show shortcut alongside command name */
.command-result {
display: flex;
justify-content: space-between;
padding: 8px 12px;
}
.command-shortcut {
font-family: var(--font-mono);
font-size: 12px;
color: var(--text-muted);
background: var(--bg-subtle);
padding: 2px 6px;
border-radius: 4px;
}
アンチパターン: 機能を説明するチュートリアルモーダル。説明は忘れられますが、実践は記憶に残ります。
AI インターフェースパターン
「最高の AI インターフェースは、機械のプロセスを可視化し、機械の出力を検証可能にするものだ。」
AI インターフェースには固有の課題があります。ユーザーは出力を予測できず、目視で正確性を検証できず、システムが正常に動作しているのか故障しているのかを判断できないことが多いのです。
核心的な課題
| 従来のソフトウェア | AI ソフトウェア |
|---|---|
| 出力は予測可能 | 出力は変動する |
| エラーは明白 | エラーがもっともらしく見える |
| テストで検証 | ソースの確認で検証 |
| ローディング=待機 | ローディング=処理中(見せるべき) |
| デフォルトで信頼 | 信頼は獲得するもの |
引用ファーストデザイン(Perplexity)
すべての事実に基づく主張は、ソースへのリンクを含む必要があります。Perplexity はすべての主張にインライン引用 [1] を埋め込み、ホバープレビューと常設のソースパネルを備えています。
.citation-marker {
position: relative;
color: var(--accent);
cursor: pointer;
font-size: 0.8em;
vertical-align: super;
}
.citation-preview {
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
width: 280px;
padding: 12px;
background: var(--bg-elevated);
border: 1px solid var(--border);
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
アンチパターン: 追跡可能なソースなしに主張を生成する AI インターフェース。モデルが引用できないなら、インターフェースがそれを明示するべきです。
ストリーミングフェーズインジケーター(Perplexity)
AI が動作中であることだけでなく、何をしているかをユーザーに示します。汎用的なスピナーの代わりに、フェーズインジケーターを使用します:「検索中…」→「4つのソースを読み込み中…」→「回答を作成中…」
.phase-indicator {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 6px 12px;
background: color-mix(in srgb, var(--phase-color) 10%, transparent);
border-radius: 16px;
font-size: 13px;
color: var(--phase-color);
transition: all 0.3s ease;
}
.loading-dots span {
width: 4px;
height: 4px;
background: currentColor;
border-radius: 50%;
animation: pulse 1.4s ease-in-out infinite;
}
エラーの透明性
AI が失敗したり不確実な場合、自信ありげなテキストの裏に隠さず、明確に表示します。
| 状況 | 悪いパターン | 良いパターン |
|---|---|---|
| 確信度が低い | 自信を持って断言する | 「確実ではありませんが…」と控えめなスタイリングで表示 |
| ソースが見つからない | テキストを捏造する | 「この主張のソースは見つかりませんでした」 |
| ソースが矛盾している | 片方を黙って選ぶ | 両方を表示し、矛盾をハイライトする |
| 情報が古い | 最新の情報として提示する | 「[日付]時点の情報…」と新しさのインジケーターを表示 |
重要なインサイト: ユーザーは不確実性に正直な AI を許容します。しかし、自信満々に間違える AI は許容しません。
Dieter Rams:良いデザインの10原則
「より少なく、しかしより良く。」 — Dieter Rams
Dieter Rams は20世紀で最も影響力のあるインダストリアルデザイナーです。1961年から1995年まで Braun のデザイン責任者として、数十年経っても色褪せないプロダクトを生み出しました。彼の仕事は Apple のデザイン言語に直接的な影響を与えています。
良いデザインの10原則
1. 良いデザインは革新的である 模倣してはいけません。進歩するテクノロジーと革新的なデザインを組み合わせます。
2. 良いデザインはプロダクトを便利にする すべての要素は目的を持たなければなりません。形態は機能に従います。
3. 良いデザインは美しい 美しさは表面的なものではなく、本質的なものです。毎日使うプロダクトは私たちの幸福に影響を与えます。
4. 良いデザインはプロダクトを分かりやすくする ユーザーに説明書は不要であるべきです。インターフェースが自ら教えてくれます。
5. 良いデザインは控えめである デザインはユーザーを圧倒するのではなく、サポートするべきです。主役はユーザーのコンテンツであり、UI ではありません。
/* Obtrusive: UI competes with content */
.editor {
background: linear-gradient(135deg, purple, blue);
border: 3px dashed gold;
}
/* Unobtrusive: UI recedes, content shines */
.editor {
background: var(--color-background);
border: 1px solid var(--color-border);
}
6. 良いデザインは誠実である ダークパターンを使ってはいけません。過大な約束をしてはいけません。制限について透明であるべきです。
7. 良いデザインは長持ちする すぐに古くなるトレンドを避けます。流行よりもクラシックを。
TRENDY (will date): TIMELESS:
- Extreme glassmorphism - Clean typography
- Neon colors, glitch effects - Subtle elevation
- Aggressive gradients - Neutral palette with considered accent
8. 良いデザインは最後のディテールまで徹底している 恣意的なものがあってはなりません。ローディング状態、空の状態、エラー状態—すべてがデザインされるべきです。
9. 良いデザインは環境に配慮している パフォーマンスは環境問題です。ユーザーの注意を尊重します。効率的なコードを書きます。
10. 良いデザインは最小限のデザインである 不要なものはすべて取り除きます。最高のデザインは目に見えないものです。
2026年のWebパターン
モダンなWebデザインは、多くのケースでJavaScriptを不要にするネイティブCSS機能を活用しています。2025〜2026年にかけて、アンカーポジショニング、スクロール駆動アニメーション、@starting-styleがプロダクションブラウザに導入されました。
Container Queries
コンポーネントのサイズをビューポートではなく、コンテナに基づいて決定します。
.card-grid {
container-type: inline-size;
container-name: card-grid;
}
.card {
display: grid;
gap: 16px;
padding: 20px;
}
@container card-grid (min-width: 400px) {
.card {
grid-template-columns: auto 1fr;
}
}
@container card-grid (min-width: 600px) {
.card {
padding: 32px;
gap: 24px;
}
}
:has() セレクタ
子要素に基づいた親要素の選択——以前はJavaScriptなしでは不可能でした。
/* Card with image gets different padding */
.card:has(img) {
padding: 0;
}
.card:has(img) .card-content {
padding: 20px;
}
/* Form group with error */
.form-group:has(.input:invalid) .form-label {
color: var(--color-error);
}
/* Highlight navigation when on that page */
.nav-item:has(a[aria-current="page"]) {
background: var(--color-surface);
}
CSSネスティング
プリプロセッサなしでネイティブにネストが可能です。
.card {
background: var(--color-surface);
border-radius: 12px;
padding: 24px;
& .card-title {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 8px;
}
& .card-body {
color: var(--color-text-secondary);
line-height: 1.6;
}
&:hover {
box-shadow: var(--shadow-md);
}
@media (min-width: 768px) {
padding: 32px;
}
}
HTMXインテグレーション
重量級JavaScriptフレームワークを使わない、サーバー駆動のインタラクティビティです。
<!-- Load content on click -->
<button hx-get="/api/more-items"
hx-target="#item-list"
hx-swap="beforeend"
hx-indicator="#loading">
Load More
</button>
<!-- Form with inline validation -->
<form hx-post="/api/contact"
hx-target="#form-response"
hx-swap="outerHTML">
<input type="email" name="email"
hx-post="/api/validate-email"
hx-trigger="blur"
hx-target="next .error" />
<span class="error"></span>
</form>
アンカーポジショニング
ある要素を別の要素に対して相対的に配置するネイティブCSSの仕組みです——JavaScriptは不要です。ツールチップ、ポップオーバー、ドロップダウンメニューがトリガー要素に追従します。
/* Anchor an element to another */
.trigger {
anchor-name: --my-trigger;
}
.tooltip {
position: fixed;
position-anchor: --my-trigger;
top: anchor(bottom);
left: anchor(center);
translate: -50% 8px;
}
スクロール駆動アニメーション
アニメーションの進行をスクロール位置に連動させます。読書プログレスインジケーター、パララックスエフェクト、表示シーケンスをJavaScriptなしで実現できます。
/* Reading progress bar */
.progress-bar {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 3px;
background: var(--color-primary);
transform-origin: left;
animation: progress linear;
animation-timeline: scroll();
}
@keyframes progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
@starting-style
DOMに追加される要素の初期スタイルを定義します——JavaScriptなしでCSSのみのエンターアニメーションが可能になります。
.card {
opacity: 1;
transform: translateY(0);
transition: opacity 0.3s ease, transform 0.3s ease;
@starting-style {
opacity: 0;
transform: translateY(10px);
}
}
デザイントークンシステム
アプリケーション全体の一貫性を保つための完全なトークンシステムです。
:root {
/* Colors */
--color-text: #1a1a1a;
--color-text-secondary: #666666;
--color-text-muted: #999999;
--color-background: #ffffff;
--color-surface: #f8f9fa;
--color-surface-elevated: #ffffff;
--color-border: #e5e7eb;
--color-primary: #3b82f6;
--color-primary-hover: #2563eb;
--color-success: #10b981;
--color-warning: #f59e0b;
--color-error: #ef4444;
/* Typography */
--font-sans: system-ui, -apple-system, sans-serif;
--font-mono: "SF Mono", Consolas, monospace;
--text-xs: 0.75rem;
--text-sm: 0.875rem;
--text-base: 1rem;
--text-lg: 1.125rem;
--text-xl: 1.25rem;
--text-2xl: 1.5rem;
--text-3xl: 2rem;
--leading-tight: 1.25;
--leading-normal: 1.5;
--leading-relaxed: 1.75;
/* Spacing (8px base) */
--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 */
/* Borders */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-full: 9999px;
/* Shadows */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
/* Transitions */
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
--duration-fast: 100ms;
--duration-normal: 200ms;
}
ダークモードを正しく実装する
単純に反転するのではなく、暗い背景に合わせて再デザインしましょう。
@media (prefers-color-scheme: dark) {
:root {
/* Neutrals */
--color-background: hsl(220, 13%, 10%);
--color-surface: hsl(220, 13%, 15%);
--color-surface-elevated: hsl(220, 13%, 18%);
--color-border: hsl(220, 13%, 23%);
/* Text (inverted) */
--color-text: hsl(220, 9%, 93%);
--color-text-secondary: hsl(220, 9%, 70%);
--color-text-muted: hsl(220, 9%, 55%);
/* Adjust saturation for dark mode */
--color-primary: hsl(220, 80%, 60%);
--color-success: hsl(142, 70%, 45%);
--color-error: hsl(0, 80%, 65%);
/* Shadows in dark mode need adjustment */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
}
}
ダークモードの原則: - 広い面積の色は彩度を下げる - アクセントカラーの明度を上げる - シャドウを強める(より高いコントラストが必要です) - ダークモードは後付けではなく、意図的にデザインする
Figma抽出ワークフロー
デザインファイルをプロダクションコードに変換するには、デザイントークン——カラー、タイポグラフィ、スペーシング、エフェクトなど、デザイン言語を定義する要素——を体系的に抽出する必要があります。
Figma Variables エクスポート
FigmaのネイティブVariables機能が最もクリーンな抽出パスを提供します。
エクスポート手順:
1. Figmaファイルを開く → Local Variablesパネル
2. コレクションメニューをクリック → “Export to JSON”
3. figma-variables.jsonとして保存
JSONトークン構造:
{
"colors": {
"primitive": {
"blue-500": { "value": "#3b82f6", "type": "color" },
"blue-600": { "value": "#2563eb", "type": "color" }
},
"semantic": {
"primary": { "value": "{colors.primitive.blue-500}", "type": "color" },
"primary-hover": { "value": "{colors.primitive.blue-600}", "type": "color" }
}
},
"spacing": {
"1": { "value": "4px", "type": "spacing" },
"2": { "value": "8px", "type": "spacing" },
"4": { "value": "16px", "type": "spacing" }
}
}
トークンからCSSへの変換
CSSカスタムプロパティ:
:root {
/* Primitive colors (direct values) */
--color-blue-50: #eff6ff;
--color-blue-100: #dbeafe;
--color-blue-500: #3b82f6;
--color-blue-600: #2563eb;
--color-blue-900: #1e3a8a;
/* Semantic colors (reference primitives) */
--color-primary: var(--color-blue-500);
--color-primary-hover: var(--color-blue-600);
--color-background: var(--color-white);
--color-surface: var(--color-gray-50);
/* Spacing (8px grid) */
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-4: 1rem; /* 16px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
/* Typography */
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
/* Effects */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
}
ダークモードトークン:
@media (prefers-color-scheme: dark) {
:root {
--color-background: var(--color-gray-900);
--color-surface: var(--color-gray-800);
--color-text: var(--color-gray-100);
--color-text-secondary: var(--color-gray-400);
/* Adjusted shadows for dark mode */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
}
}
トークンからSwiftUIへの変換
Colorエクステンション:
import SwiftUI
extension Color {
// MARK: - Primitive Colors
static let blue50 = Color(hex: "eff6ff")
static let blue500 = Color(hex: "3b82f6")
static let blue600 = Color(hex: "2563eb")
// MARK: - Semantic Colors
static let brandPrimary = Color.blue500
static let brandPrimaryHover = Color.blue600
// MARK: - Surface Colors
static let surfaceBackground = Color(light: .white, dark: Color(hex: "0f172a"))
static let surfaceElevated = Color(light: Color(hex: "f8fafc"), dark: Color(hex: "1e293b"))
}
extension Color {
init(hex: String) {
// Standard hex parsing implementation
}
init(light: Color, dark: Color) {
self.init(UIColor { traits in
traits.userInterfaceStyle == .dark ? UIColor(dark) : UIColor(light)
})
}
}
スペーシング定数:
enum Spacing {
static let xs: CGFloat = 4 // --space-1
static let sm: CGFloat = 8 // --space-2
static let md: CGFloat = 16 // --space-4
static let lg: CGFloat = 24 // --space-6
static let xl: CGFloat = 32 // --space-8
}
// Usage
VStack(spacing: Spacing.md) {
// ...
}
.padding(Spacing.lg)
デザイナーハンドオフチェックリスト
デザイナーがエクスポートすべきもの:
| アセットタイプ | フォーマット | 備考 |
|---|---|---|
| カラー | Variables JSON | ライトモード+ダークモードを含む |
| タイポグラフィ | スタイルエクスポート | フォント、サイズ、ウェイト、行間 |
| スペーシング | Variables JSON | 基準単位を明記 |
| アイコン | SVG | アウトライン化、単色 |
| 画像 | PNG @2x/@3x または WebP | 圧縮済み |
| コンポーネント | Figmaリンク | 実装時の参照用 |
品質ゲート基準:
- [ ] すべてのカラーがVariablesとして定義されている(ハードコードされたHEX値なし)
- [ ] タイポグラフィが定義済みテキストスタイルを使用している
- [ ] スペーシングがグリッドシステムに従っている(8px基準)
- [ ] ダークモードのバリエーションが提供されている
- [ ] インタラクティブステート(hover、active、disabled)が文書化されている
- [ ] レスポンシブブレークポイントが注釈されている
- [ ] アクセシビリティ要件が記載されている(コントラスト比)
開発者が受け取るもの:
- トークンファイル(プラットフォームに応じてJSON/CSS/Swift)
- 寸法付きコンポーネント仕様書
- 必要なフォーマットのアセットエクスポート
- インタラクションドキュメント(ステート、アニメーション)
- アクセシビリティに関する注釈
クイックリファレンス表
Gestalt原則
| 原則 | ルール | 用途 |
|---|---|---|
| 近接 | 関連するものは近くに配置 | フォーム、セクション |
| 類似 | 同じ見た目=同じ機能 | ボタン、カード |
| 図と地 | 明確なレイヤー分離 | モーダル、カード |
| 連続 | 線に沿って視線を誘導 | タイムライン、整列 |
| 閉合 | 脳が形を補完する | アイコン、スクロールヒント |
タイポグラフィ
| 要素 | サイズ | ウェイト | 行間 |
|---|---|---|---|
| 本文 | 16px | 400 | 1.5-1.7 |
| 見出し | 24-48px | 600-700 | 1.1-1.2 |
| UIラベル | 12-14px | 500 | 1.3-1.4 |
| キャプション | 12px | 400 | 1.4 |
カラーの役割
| 役割 | ライトモード | ダークモード |
|---|---|---|
| 背景 | #ffffff | #0f172a |
| サーフェス | #f4f5f7 | #1e293b |
| ボーダー | #e4e6ea | #334155 |
| テキスト | #1a1a2e | #f1f5f9 |
| テキスト(ミュート) | #6b7280 | #94a3b8 |
| プライマリ | #3b82f6 | #60a5fa |
| 成功 | #22c55e | #4ade80 |
| エラー | #ef4444 | #f87171 |
スペーシングスケール
| トークン | 値 | 用途 |
|---|---|---|
| –space-1 | 4px | アイコンの間隔 |
| –space-2 | 8px | インライン要素 |
| –space-4 | 16px | デフォルトの間隔 |
| –space-6 | 24px | カードのパディング |
| –space-8 | 32px | セクションの間隔 |
| –space-16 | 64px | ページセクション |
デザインチェックリスト
インターフェースをリリースする前に、以下を確認してください:
Gestalt
- [ ] 関連する要素は、無関係な要素よりも近くに配置されている(近接)
- [ ] 似た機能には似たスタイルが適用されている(類似)
- [ ] 前景と背景が明確に分離されている(図と地)
- [ ] レイアウト内で視線が自然に流れる(連続)
タイポグラフィ
- [ ] ベースフォントサイズが16px以上である
- [ ] 本文の行の高さが1.5以上である
- [ ] 1行の文字数が75文字以内である
- [ ] 階層構造が明確である(3段階が区別できる)
- [ ] 一貫したスケールが全体に適用されている
カラー
- [ ] すべてのテキストが4.5:1のコントラスト比をクリアしている(WCAG AA)
- [ ] 色だけに頼らず、アイコンやラベルも併用している
- [ ] ダークモードが意図的にデザインされている
- [ ] 60-30-10の配分が守られている
ビジュアル階層
- [ ] 最も重要な要素が一目で識別できる
- [ ] 意図した順序で視線が流れる
- [ ] セクションごとに明確なCTAが1つある
- [ ] タイプスケールが一貫している
スペーシング
- [ ] すべての余白が定義されたスケールを使用している(マジックナンバーなし)
- [ ] カードやコンポーネントのパディングが統一されている
- [ ] モバイルでの余白が快適である
- [ ] グリッドの整列が一貫している(8pxベース)
インタラクション
- [ ] ユーザーがツールを意識せずに目的を達成できるか?
- [ ] UIが現在のコンテキストに適応しているか?
- [ ] ツールは必要なときだけ表示されているか?
- [ ] 繰り返し使うことで、より速い操作方法を学べるか?
AIインターフェース
- [ ] すべての事実に基づく主張に追跡可能な出典があるか?
- [ ] ストリーミング中に、スピナーだけでなく処理フェーズが表示されるか?
- [ ] エラー状態が隠されず、透明に表示されるか?
- [ ] 確信度の低い出力が視覚的に区別されているか?
Dieter Ramsチェック
- [ ] 取り除けるものはないか?
- [ ] すべての要素が機能を果たしているか?
- [ ] 5年後に古く見えないか?
- [ ] すべての状態をデザインしたか?
リソース
書籍: - As Little Design as Possible(Sophie Lovell著、Dieter Ramsについて) - The Elements of Typographic Style(Robert Bringhurst著)
ツール: - WebAIM Contrast Checker - Type Scale Generator - Figma Tokens Studio — デザイントークン管理
デザインシステム: - Apple HIG - Material Design 3 - Radix UI - shadcn/ui
デザインスタディ
16の優れたプロダクトを深掘りし、参考にすべきパターンと原則を記録しています。
開発者ツール
| プロダクト | 主な貢献 |
|---|---|
| Figma | マルチプレイヤープレゼンス、コンテキスト対応パネル |
| Warp | ブロックベースのターミナル、CLI-GUIブリッジ |
| Framer | ビジュアルレスポンシブデザイン、プロパティコントロール |
| Vercel | ダークモードの卓越性、アンビエントステータス |
| Linear | Optimistic UI、キーボードファーストのワークフロー |
| Raycast | 拡張システム、クイックアクション |
iOSネイティブ(Apple Design Award受賞作)
| プロダクト | 主な貢献 |
|---|---|
| Flighty | 15のスマートステート、Live Activities、データビジュアライゼーション |
| Halide | インテリジェントアクティベーション、ジェスチャーコントロール |
| Bear | タイポグラフィファースト、インラインタグ付け |
| Craft | ネイティブファーストのクロスプラットフォーム、ネストページ |
| Things | 延期日付、クイックエントリーパターン |
プロダクティビティ & AI
| プロダクト | 主な貢献 |
|---|---|
| Superhuman | 100msルール、コマンドパレットトレーニング、実践的オンボーディング |
| Perplexity | 引用重視のAI、ストリーミングフェーズ |
| Notion | ブロックシステム、スラッシュコマンド |
| Arc | スペース、スプリットビュー、コマンドバー |
| Stripe | ドキュメントの卓越性、APIデザイン |
このガイドは実践を通じて成長していきます。デザインの原則は普遍的ですが、その応用はテクノロジーと理解の進化とともに変わり続けます。