frontend-ui-design について
frontend-ui-design は、フロントエンド UI の設計と実装を支援するスキルです。コンポーネント構成、レスポンシブ対応、アクセシビリティ、状態管理、パフォーマンスの判断を案内します。
主な機能
- 01コンポーネント構成の選択
- 02レスポンシブ設計の計画
- 03WCAG アクセシビリティの指針
- 04状態管理方法の選択
- 05パフォーマンス最適化チェックリスト
- 06デザインシステムとの統合
活用シーン
- 01新しいフロントエンドコンポーネントの設計
- 02端末ごとのレスポンシブ動作の確認
- 03キーボードとスクリーンリーダー対応の仕様化
- 04UI データの状態管理方法の選択
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pixel-process-ug/ superkit-agents --skill frontend-ui-designインストール後、Claude Code で/frontend-ui-designを入力して読み込まれたか確認します。
詳細
フロントエンド UI デザイン
概要
一貫したアーキテクチャ、アクセシビリティ、レスポンシブな動作、パフォーマンスを備えたフロントエンドユーザーインターフェースの設計と実装をガイドします。このスキルでは、コンポーネントのパターン、デザインシステムとの統合、状態管理の選択、WCAG への準拠を扱い、テスト可能で、アクセシブルかつ高性能なコンポーネントを作成します。
開始時に伝えること:「UI を設計するため、frontend-ui-design スキルを使用します。」
フェーズ 1:要件の把握
UI の要件を理解するため、以下の質問をします。
| # | 質問 | 判断する内容 |
|---|---|---|
| 1 | どのコンポーネントまたはページを作成しますか? | 範囲と複雑さ |
| 2 | 使用するフレームワーク/ライブラリは何ですか?(React、Vue、Svelte など) | コードパターン |
| 3 | 既存のデザインシステムまたはコンポーネントライブラリはありますか? | 制約 |
| 4 | どのデバイスに対応する必要がありますか?(モバイル、タブレット、デスクトップ) | レスポンシブ戦略 |
| 5 | アクセシビリティ要件はありますか?(WCAG レベル) | アクセシビリティ基準 |
| 6 | このコンポーネントにはどのようなデータが必要ですか? | 状態管理の方針 |
要件の把握後は必ず停止し、設計に進む前に制約と方針の概要を提示します。
フェーズ 2:コンポーネントアーキテクチャの選択
アーキテクチャパターンの判断表
| パターン | 使用する場面 | 使用しない場面 |
|---|---|---|
| アトミックデザイン | コンポーネントライブラリをゼロから構築する場合 | 既存のシステムにコンポーネントを 1 つ追加する場合 |
| 複合コンポーネント | レイアウトの柔軟性が必要な複数パーツのコンポーネント | 単純で用途が 1 つのコンポーネント |
| フックパターン | 同じロジックを異なる UI 間で再利用する場合 | 特定の 1 つのコンポーネントに結び付いたロジック |
| コンテナー/プレゼンター | コンポーネントを分離してテストする必要がある場合、または複数のデータソースを扱う場合 | ロジックが最小限のシンプルなコンポーネント |
アトミックデザインのレベル
| レベル | 説明 | 例 |
|---|---|---|
| アトム | 最小の構成要素で、目的は 1 つ | Button、Input、Label、Icon |
| モレキュール | 連携して機能するアトムのグループ | SearchBar(Input + Button)、FormField(Label + Input + Error) |
| オーガニズム | モレキュールで構成される複雑なセクション | Header(Logo + Nav + SearchBar)、ProductCard |
| テンプレート | プレースホルダーコンテンツを含むページレイアウト | DashboardLayout、AuthLayout |
| ページ | 実際のデータを反映したテンプレート | HomePage、SettingsPage |
複合コンポーネントの例
<Select value={selected} onChange={setSelected}>
<Select.Trigger />
<Select.Options>
<Select.Option value="a">Option A</Select.Option>
<Select.Option value="b">Option B</Select.Option>
</Select.Options>
</Select>
使用する場面:コンポーネントに連携が必要なサブパーツが複数ある一方、利用者にはレイアウトの柔軟性が必要な場合。
フックパターンの例
function useDialog() {
const [isOpen, setIsOpen] = useState(false);
const open = () => setIsOpen(true);
const close = () => setIsOpen(false);
return { isOpen, open, close };
}
使用する場面:異なる UI を持つ複数のコンポーネントで同じロジックが必要な場合。
アーキテクチャの選択後は必ず停止し、先に進む前にパターンの選択を確認します。
フェーズ 3:レスポンシブデザイン
モバイルファーストのブレークポイント
| ブレークポイント | 対象 | 最小幅 |
|---|---|---|
| sm | モバイル(横向き) | 640px |
| md | タブレット | 768px |
| lg | デスクトップ | 1024px |
| xl | 大型デスクトップ | 1280px |
| 2xl | ワイドデスクトップ | 1536px |
レスポンシブ戦略の判断表
| 要件 | 使用するもの | 使用しないもの |
|---|---|---|
| ビューポートサイズに応じてレイアウトを変更する | メディアクエリ | コンテナクエリ |
| 親コンテナーのサイズに応じてコンポーネントを適応させる | コンテナクエリ | メディアクエリ |
| ブレークポイント間でテキストを滑らかに拡大縮小する | clamp() による流動的なタイポグラフィ | 固定フォントサイズ |
| 画像をビューポートに適応させる | srcset + sizes | 固定画像 1 枚 |
流動的なタイポグラフィ
font-size: clamp(1rem, 0.5rem + 1.5vw, 1.5rem);
フェーズ 4:アクセシビリティ(WCAG 2.1 AA)
セマンティック HTML の判断表
| 要件 | 使用するもの | 使用しないもの |
|---|---|---|
| ナビゲーション | <nav> | <div class="nav"> |
| ボタン操作 | <button> | <div onClick> |
| ページセクション | <main>、<section>、<aside> | <div> |
| 見出し | <h1>~<h6>を順番に使用 | <div class="heading"> |
| 項目のリスト | <ul>、<ol> | 入れ子の<div> |
| フォームのラベル | <label for="..."> | プレースホルダーテキストのみ |
ARIA の使用ルール
| ルール | 適用する場合 |
|---|---|
| まずセマンティック HTML を使用する | 常に。ARIA は代替手段です |
aria-label | 表示テキストのない要素のラベル |
aria-describedby | 説明テキストを要素に関連付けます |
aria-live | 動的なコンテンツの変更を通知します |
aria-expanded | 切り替え可能なセクション(アコーディオン、メニュー) |
role | セマンティック要素が存在しない場合に限ります |
キーボードナビゲーションの要件
- すべてのインタラクティブ要素をフォーカス可能にします(標準の動作、または
tabindex="0") - キーボードで操作できるようにします(Enter、Space、Escape、矢印キー)
- フォーカスインジケーターを表示します(代替手段なしに
outline: noneを指定しないでください) - 視覚的な順序に合った論理的なタブ順序にします
- モーダルとダイアログではフォーカストラップを設けます
色のコントラスト要件
| 要素 | 最小比率 |
|---|---|
| 通常のテキスト | 4.5:1 |
| 大きなテキスト(18px 以上、または太字の 14px 以上) | 3:1 |
| UI コンポーネント | 隣接する色に対して 3:1 |
| 色で伝える情報 | アイコン、パターン、またはテキストも併用する必要があります |
スクリーンリーダーでのテスト
少なくとも 1 つのスクリーンリーダーでテストします:
- macOS:VoiceOver(標準搭載)
- Windows:NVDA(無料)または JAWS
- 確認事項:コンテンツが論理的な順序で読み上げられること、フォームのエラーが入力欄に関連付けられていること、動的な更新が通知されること
フェーズ 5:状態管理とパフォーマンス
状態管理の選択表
| 状態の種類 | 解決策 | 適用する場合 |
|---|---|---|
| ローカル | useState、useReducer | 1 つのコンポーネントまたは直接の子コンポーネントで使用する状態 |
| 共有 | Context、Zustand、Jotai | 複数の関連しないコンポーネント間で共有する状態 |
| サーバー | TanStack Query、SWR | API から取得し、キャッシュや再検証が必要なデータ |
| フォーム | React Hook Form、Formik | バリデーションと送信を伴う複雑なフォーム |
| URL | 検索パラメーター、ルーターの状態 | ブックマークや共有が可能であるべき状態 |
選択のヒューリスティック
useStateから始め、実際の制約に直面した場合にのみ段階的に移行します- props のバケツリレーが 2 階層を超えたら、Context または状態管理ライブラリを検討します
- API レスポンスをキャッシュする場合は、サーバー状態管理ライブラリを使用します(サーバー状態に Redux は使用しないでください)
- バリデーションを伴うフィールド数が 3 を超えるフォームでは、フォームライブラリを使用します
パフォーマンス最適化チェックリスト
| 手法 | 適用する場合 |
|---|---|
React.lazy() + Suspense | ルート単位のコード分割 |
画像の loading="lazy" | ファーストビューより下にある画像 |
| 仮想化 | 項目数が 50 を超えるリスト |
useMemo | 計算コストの高い処理 |
useCallback | メモ化された子コンポーネントに渡すコールバック |
動的な import() | 条件付きで読み込む重いライブラリ |
| WebP/AVIF 画像 | すべての画像アセット |
画像の明示的な width/height | レイアウトシフトの防止 |
デザインシステムの統合
デザイントークン — ハードコードせず、基礎となる値を定義します:
const tokens = {
color: { primary: '#2563eb', secondary: '#64748b', error: '#dc2626' },
spacing: { xs: '0.25rem', sm: '0.5rem', md: '1rem', lg: '1.5rem', xl: '2rem' },
typography: { fontFamily: { sans: 'Inter, system-ui, sans-serif' } },
};
コンポーネントのバリアント — 一貫性のあるバリアント API:
<Button variant="primary" size="md">Save</Button>
<Button variant="outline" size="sm">Cancel</Button>
テーマのサポート:
- 実行時のテーマ切り替えには CSS カスタムプロパティを使用します
- 最低限、ライトテーマとダークテーマをサポートします
- デフォルトでは
prefers-color-schemeに従います - localStorage に保存されたユーザー設定による上書きを許可します
デザインの後で停止し、レビュー用にコンポーネントの仕様全体を提示してください。
アンチパターン/よくある間違い
| 間違い | 問題である理由 | 代わりにすべきこと |
|---|---|---|
<button> ではなく <div onClick> を使う | キーボードで操作できず、スクリーンリーダー向けのセマンティクスもありません | セマンティックな HTML 要素を使います |
代替手段なしで outline: none を使う | キーボードユーザーがフォーカス位置を確認できません | 視認できるフォーカススタイルに置き換えます |
| フォントサイズを px で固定する | ユーザー設定に合わせて拡大できません | rem と clamp() を使います |
| 4 階層以上にわたってプロパティを受け渡す | 保守が非常に困難になります | Context または状態管理ライブラリを使います |
| useEffect と useState でデータを取得する | キャッシュも重複排除もなく、競合状態が発生します | TanStack Query または SWR を使います |
| 時期尚早なメモ化 | 効果を測定せずに複雑さだけが増します | まずプロファイリングを行い、測定で確認されたボトルネックを最適化します |
| デスクトップファーストのレスポンシブデザイン | モバイルでの使いやすさが後回しになります | モバイルファーストで始め、段階的に複雑さを加えます |
| 情報を色だけで伝える | 色覚異常のあるユーザーにはアクセスできません | アイコン、パターン、またはテキストラベルを追加します |
| ローディング/エラー状態がない | ユーザーには空白の画面やわかりにくいエラーが表示されます | ローディング、エラー、空の状態を設計します |
不合理な正当化を防ぐためのガード
- アクセシビリティを省略しないでください。WCAG 2.1 AA は最低基準であり、任意ではありません
- セマンティックな要素ではなく、onClick を指定した
<div>を使わないでください - キーボード操作のテストを省略しないでください
- 実際のニーズを理解する前に、状態管理の方法を選ばないでください
- 発見フェーズを省略しないでください。まず制約を理解してください
- 事前に測定せずにパフォーマンスを最適化しないでください
統合ポイント
| スキル | 関係 |
|---|---|
api-design | 上流:API のレスポンス形状がコンポーネントに必要なデータを決定します |
spec-writing | 上流:仕様がコンポーネントの動作要件を定義します |
planning | 下流:コンポーネントの設計が実装タスクになります |
test-driven-development | 下流:コンポーネント仕様をもとに、テストファーストで実装します |
senior-frontend | 並行:React/Next.js の詳細に関する専門知識を提供します |
ui-ux-pro-max | 上流:UX 設計がコンポーネントの要件を示します |
ui-design-system | 並行:デザインシステムのトークンをコンポーネントのスタイリングに活用します |
performance-optimization | 下流:実装後にプロファイリングと最適化を行います |
検証ゲート
UI 設計が完了したとする前に、次の項目を確認してください。
- コンポーネントアーキテクチャのパターンが、根拠とともに明確に選択されていることを確認します
- 対象となるすべてのブレークポイントで、レスポンシブな動作が定義されていることを確認します
- アクセシビリティ要件(WCAG レベル、キーボード操作、色のコントラスト)が指定されていることを確認します
- 実際のニーズに基づいて、状態管理の方法が選択されていることを確認します
- ローディング、エラー、空の状態が設計されていることを確認します
- ユーザーがコンポーネント仕様を承認していることを確認します
スキルの種類
柔軟型 — アクセシビリティ要件と発見を優先するアプローチを維持しながら、プロジェクトのフレームワークと制約に合わせて、コンポーネントのパターン、レスポンシブ戦略、状態管理を調整します。