UX Contract
本プロダクトにおけるUXは、機能を誇示するためではなく、 ユーザーの目的達成を最短化するために存在する。
抽象原則
役割を終えたらすぐに消える
UIは目的を果たした瞬間に退く。永続的に居座らない。
- Toastは3秒以内に自動消去
- 一時的ヒントは再表示しない
- オンボーディングは完了後に消える
保存完了
ユーザーを邪魔しない
注意を奪わない。強制しない。モーダルは最小限。
- 自動フォーカスは慎重に
- 不要なconfirmは出さない
- ポップアップ禁止
ユーザーに考えさせない
選択肢は整理されている。言葉は明確。状態は常に可視化されている。
- ボタン文言は動詞で終わる
- エラーは原因と解決策を示す
- 現在地を常に表示
Good
Bad
迷わせない
1画面1目的。階層は浅く。戻れる導線を必ず置く。
現在地が明確
パンくずリストで常に階層を表示
音量を上げない
色も動きも控えめ。主張しすぎない。
静かなUI
騒がしいUI
インタラクション原則
即時フィードバック
クリック後100ms以内に反応を返す。ローディングは即表示。
不可逆操作は明確に
削除は赤。Undoを可能にする。
デフォルトは安全側
破壊的操作は初期選択にしない。
本当に削除しますか?
この操作は取り消せません。
フォーカスは視覚化する
キーボード操作を前提とする。
focus-visible:ring-2 ring-ds-sky
レイアウト契約
スクロールは自然である
不必要な内部スクロールを作らない。ページ外バウンスによる視覚ノイズを防ぐ。
overscroll-behavior: none;モーダルは画面を閉じ込めない
高さは90vh以下。内部スクロールは必要最小限。
Good
Bad
スクロール位置は保持する
戻ったとき、位置を復元する。
↑ 前回のスクロール位置を復元
モーション契約
アニメーションは意味を持つ
装飾ではなく状態変化を示す。duration: 0.2–0.4s / easing: ease-out / 不要なバウンス禁止。
duration: 0.3s / ease-out
自動再生をしない
動画・音声は必ずユーザー操作後。
ユーザーが再生ボタンを押すまで停止
フォーム契約
リアルタイムバリデーション
送信後にまとめて怒らない。
入力途中でエラー表示しない
フォーカスアウト後に表示。
onBlur で検証
onChange で即エラー
メールアドレスが無効です
必須項目は最小限
「必要」の定義を厳格に。
必須は1項目のみ
表示契約
Skeletonを使う
空白は放置しない。
Empty Stateは指示を含む
「データがありません」で終わらせない。
プロジェクトがありません
最初のプロジェクトを作成して始めましょう
数値は意味を添える
前月比、単位、文脈を明示。
月間アクティブユーザー
前月比 +1,412人
パフォーマンス契約
初期表示は2秒以内
体感速度を最優先。
不要な再レンダリングを避ける
スクロール中にレイアウトが揺れない。
layout-stable · no CLS
言葉の契約
曖昧な言葉を使わない
「実行」「処理」など抽象語を避ける。
明確な言葉
曖昧な言葉
謝りすぎない
エラーは冷静に説明する。
冷静な説明
接続エラー
過剰な謝罪
管理画面特有の契約
一括操作は常に明示
Bulk Actionは選択時のみ表示。
状態は色だけに依存しない
テキストと併用。
テキスト + 色
色のみ
UIの撤退原則
使われない機能は隠す
設定は段階的に開示。
役割を終えたら消える
Contract 01 の再掲。UIは目的を果たした瞬間に退く。
完了
この画面は自動的に閉じます
まとめ
このUX契約の核:
- 目立たない
- 迷わせない
- 居座らない
- 揺らがない
- 強制しない
UIは舞台装置であり、主役は常にユーザーである。