1---2name: keyboard-shortcuts3description: UIキーボードショートカットを「公式基準(W3C APG / WCAG)+プラットフォーム規約(Apple HIG / Fluent UI)+デファクトスタンダード(GitHub・Gmail・Slack等)」に沿って設計し、衝突なく・発見しやすく・無効化可能な形で実装するための判断軸。4---56# Keyboard Shortcuts Skill78## 発火条件(適用タイミング)9- 依頼が「キーボードショートカット」「キーバインド」「ホットキー」「ショートカットキー」「キーボードナビゲーション」なら適用する。10- UI実装(`/design-ui` / `/design-assemble` / フロント実装)でインタラクティブ要素を扱うとき、必要に応じて併用する。11- `accessibility-engineer` skill と組み合わせて使うことが多い(キーボード操作全般はそちらが基本、このskillはショートカット設計に特化)。1213## このSkillの基本方針(整理軸)14- **公式基準ファースト**: W3C APG のキーボードパターンと WCAG 2.1/2.2 の成功基準を最上位の根拠とする。15- **プラットフォーム規約の尊重**: OS予約キー(macOS: ⌘+Space, ⌘+Tab 等 / Windows: Win+L 等)やブラウザ標準キー(Ctrl+T, Ctrl+W 等)を奪わない。16- **デファクトの活用**: GitHub・Gmail・Slack・X 等で広く定着したパターン(`?` でヘルプ、`/` で検索、`j`/`k` でリスト移動等)を文脈に応じて採用し、ユーザーの学習コストを下げる。17- **発見可能性と無効化**: ショートカットは隠れ機能ではない。一覧表示(`?`)・ツールチップ・無効化/リマップ手段を必ず提供する。1819## 思想(判断ルール)2021### 1) 公式基準への準拠(WCAG / APG)22- **WCAG 2.1.1 (A)**: すべての機能がキーボードで操作可能であること。ショートカットは利便性の追加であり、ショートカットなしでも機能が使えることが前提。23- **WCAG 2.1.2 (A)**: キーボードトラップを作らない。モーダル内のフォーカストラップは例外だが、`Escape` で必ず脱出可能にする。24- **WCAG 2.1.4 (A)**: **単独文字キー**(修飾キーなし)のショートカットには、以下のいずれかを提供する:25 1. 無効化する仕組み26 2. 修飾キー付きにリマップする仕組み27 3. コンポーネントがフォーカスを持つ時のみ有効にする28- **WCAG 2.4.7 (AA)**: フォーカスインジケーターを常に可視にする。ショートカットでフォーカス移動した先も同様。29- **参照**: [WAI-ARIA APG Keyboard Interface](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/) / [APG Patterns](https://www.w3.org/WAI/ARIA/apg/patterns/)3031### 2) 複合ウィジェットのキーボードパターン(APG準拠)32以下はAPGが定めるウィジェット別の標準キー割り当て。独自実装せず、このパターンに従う。3334| ウィジェット | 内部移動 | 主要キー |35|-------------|---------|---------|36| Tabs | 左右矢印(水平)/ 上下矢印(垂直) | Home, End, Delete(閉じる) |37| Menu / Menubar | 上下矢印(縦)/ 左右矢印(横) | Enter/Space(実行), Escape(閉じる) |38| Listbox | 上下矢印 | Home, End, Type-ahead |39| Grid | 上下左右矢印 | PageUp/Down, Ctrl+Home/End |40| Tree View | 上下矢印, 左(折畳), 右(展開) | Enter(実行), `*`(全展開) |41| Dialog (Modal) | Tab(内部循環) | Escape(閉じる), フォーカストラップ必須 |42| Combobox | 上下矢印(ポップアップ内) | Escape(閉じる), Enter(選択) |43| Radio Group | 上下/左右矢印 | Space(選択) |44| Toolbar | 左右矢印 | Home, End |4546- **フォーカス管理**: Roving Tabindex(フォーカス中 `tabindex="0"` / 他 `tabindex="-1"`)または `aria-activedescendant` を使い分ける。4748### 3) プラットフォーム規約(衝突回避)4950#### 修飾キーのクロスプラットフォーム対応51| 機能 | macOS | Windows / Linux |52|------|-------|-----------------|53| アプリコマンド | `⌘ Cmd` | `Ctrl` |54| 代替操作 | `⌥ Option` | `Alt` |55| 逆方向/拡張 | `⇧ Shift` | `Shift` |5657#### 予約済みキー(絶対に奪わない)58- **macOS**: `⌘+Space`(Spotlight), `⌘+Tab`(アプリ切替), `⌘+Q`(終了), `⌘+H`(隠す), `⌘+M`(最小化), `Ctrl+F1`/`Ctrl+F7`(キーボードアクセス)59- **Windows**: `Win+L`(ロック), `Alt+Tab`(切替), `Alt+F4`(終了), `Ctrl+Alt+Del`60- **ブラウザ共通**: `Ctrl/⌘+T`(新規タブ), `Ctrl/⌘+W`(タブを閉じる), `Ctrl/⌘+L`(アドレスバー), `F5/⌘+R`(更新), `Ctrl/⌘+F`(ページ内検索)61- **支援技術**: CapsLock / Insert(スクリーンリーダの修飾キーとして使用)は避ける62- **参照**: [Apple HIG - Keyboards](https://developer.apple.com/design/human-interface-guidelines/keyboards) / [macOS ショートカット一覧](https://support.apple.com/en-us/102650)6364### 4) デファクトスタンダード(業界共通パターン)65主要サービス(GitHub / Gmail / Slack / X / Notion / VS Code)で共通して定着しているパターン。文脈が合えば積極的に採用する。6667#### グローバルショートカット(ページ全体)68| キー | 機能 | 採用例 |69|------|------|--------|70| `?` | ショートカットヘルプ一覧を表示 | GitHub, Gmail, X |71| `/` | 検索バーにフォーカス | GitHub, X, YouTube |72| `Escape` | モーダル/ポップアップ/ドロワーを閉じる | 全サービス共通 |73| `⌘/Ctrl+K` | コマンドパレット / クイックスイッチャー | GitHub, Slack, VS Code, Linear |7475#### リスト/フィード操作(vim風)76| キー | 機能 | 採用例 |77|------|------|--------|78| `j` | 次の項目へ移動 | Gmail, X, GitHub |79| `k` | 前の項目へ移動 | Gmail, X, GitHub |80| `o` / `Enter` | 選択した項目を開く | Gmail, X |81| `x` | 項目を選択/チェック | Gmail |8283#### ページナビゲーション(シーケンシャルキー)84| キー | 機能 | 採用例 |85|------|------|--------|86| `g` → `h` | ホームへ移動 | X |87| `g` → `i` | Inbox / Issues へ移動 | Gmail, GitHub |88| `g` → `n` | 通知へ移動 | X |89| `g` → `p` | プロフィール / Pull Requests へ移動 | X, GitHub |9091#### アクション92| キー | 機能 | 採用例 |93|------|------|--------|94| `n` / `c` | 新規作成(ポスト / メール / Issue) | X (`n`), Gmail (`c`) |95| `r` | 返信 | X, Gmail |96| `l` / `s` | いいね / スター | X (`l`), Gmail (`s`) |9798### 5) 実装時の原則99- **KeyboardEvent.key を使う**: `keyCode`(非推奨)ではなく `event.key` で判定する。物理配置が重要な場合(ゲーム等)は `event.code` を使い分ける。参照: [W3C UI Events KeyboardEvent key Values](https://www.w3.org/TR/uievents-key/)100- **修飾キーの正規化**: macOS の `⌘` と Windows の `Ctrl` を同一機能にマッピングする(`event.metaKey || event.ctrlKey`)。101- **シーケンシャルキー**: `g` → `i` のような2打鍵は、タイムアウト(500〜1000ms)を設け、中間状態を視覚的にフィードバックする。102- **入力フィールドとの競合回避**: `<input>`, `<textarea>`, `[contenteditable]` にフォーカスがある時はグローバルショートカットを無効化する。103- **カスタマイズ対応**: ユーザーがショートカットを無効化・リマップできるUIまたは設定を提供する(WCAG 2.1.4 対応)。104105## 進め方(最初に確認する問い)1061. このUIのどの機能にショートカットを割り当てる?(全機能にショートカットは不要。頻度の高い操作を優先)1072. ターゲットプラットフォームは?(Web / macOS / Windows / クロスプラットフォーム)1083. リスト/フィード型のUI要素はある?(`j`/`k` パターンの適用判断)1094. コマンドパレットは実装する?(`⌘/Ctrl+K` パターン)1105. 既存のショートカットフレームワーク/ライブラリの有無は?(tinykeys, hotkeys-js, Mousetrap 等)111112## 出力フォーマット(実装時)1131. **ショートカット一覧表**: 機能 / キー / 文脈(グローバル or フォーカス内) / 参照元(APG / デファクト / カスタム)1142. **衝突チェック**: OS予約 / ブラウザ標準 / 支援技術との衝突がないか1153. **WCAG 2.1.4 対応**: 単独文字キーの無効化/リマップ/フォーカス限定の方針1164. **フォーカス管理**: ショートカット発動後のフォーカス移動先の定義1175. **発見可能性**: `?` ヘルプ / ツールチップ / ドキュメントの提供方針1186. **実装方針**: イベントハンドリング・ライブラリ選定・テスト計画119120## チェックリスト121### 基本要件(WCAG準拠)122- [ ] すべてのインタラクティブ要素がキーボードで操作可能(2.1.1)123- [ ] キーボードトラップが存在しない(2.1.2)124- [ ] 単独文字キーショートカットに無効化/リマップ/フォーカス限定を提供(2.1.4)125- [ ] フォーカスインジケーターが可視(2.4.7)126- [ ] フォーカスが他要素に遮蔽されない(2.4.11)127128### 衝突回避129- [ ] OS予約キー(⌘+Space, Win+L 等)と衝突しない130- [ ] ブラウザ標準キー(⌘+T, ⌘+W, ⌘+F 等)と衝突しない131- [ ] 支援技術の修飾キー(CapsLock, Insert)を使用していない132- [ ] テキスト入力中にグローバルショートカットが誤発動しない133134### デファクト準拠135- [ ] リスト/フィード操作に `j`/`k` パターンを採用しているか検討した136- [ ] 検索フォーカスに `/` パターンを採用しているか検討した137- [ ] ショートカットヘルプ表示(`?`)を提供した138- [ ] `Escape` でモーダル/ポップアップが閉じる139140### 実装品質141- [ ] `event.key` を使用している(`keyCode` 非推奨)142- [ ] macOS / Windows のクロスプラットフォーム対応をした143- [ ] シーケンシャルキーにタイムアウトとフィードバックがある144- [ ] ショートカット一覧が文書化されている145146## よくある落とし穴147- **OS/ブラウザ予約キーの上書き** — ユーザーの基本操作を壊す。事前に衝突テーブルを確認する。148- **入力フィールド内での誤発動** — `<input>` / `<textarea>` にフォーカスがあるのに `j`/`k` が発動してリスト移動する。フォーカス対象の判定を怠らない。149- **WCAG 2.1.4 違反** — `j`/`k`/`n` 等の単独文字キーを実装して無効化手段を提供しない。音声入力ユーザーのディクテーション中に誤発動する。150- **フォーカス移動先の未定義** — ショートカットで画面遷移した後、フォーカスがページ先頭に戻る。移動先を明示的に設計する。151- **ショートカットの過剰割り当て** — すべての機能にキーを割り当てようとして、覚えきれない・衝突する。頻度の高い操作10〜20個に絞る。152- **修飾キーの不統一** — macOS で `⌘+K`、同じ機能を Windows で `Alt+K` にする等、プラットフォーム間で対応がバラバラ。`⌘` ↔ `Ctrl` の対応を守る。153- **プラットフォーム検出の誤り** — `navigator.platform`(非推奨)に依存する。`navigator.userAgentData` や feature detection を使う。154- **`keyCode` / `which` の使用** — 非推奨でロケール依存の問題がある。`event.key` を使う。155156## 短問テンプレ(不足情報を推測しない)157- このアプリのメインの操作パターンは?(リスト閲覧 / エディタ / ダッシュボード / フォーム中心)158- ターゲットプラットフォームは?(Web専用 / Electron / PWA / ネイティブアプリ)159- 既存のキーボードショートカットがあるか?(あればリストを提示してもらう)160- ユーザーがショートカットをカスタマイズできる必要はあるか?161162## 参照ドキュメント163### 公式基準164- [W3C WAI-ARIA Authoring Practices Guide (APG)](https://www.w3.org/WAI/ARIA/apg/)165- [APG - Developing a Keyboard Interface](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/)166- [WCAG 2.1 - 2.1.4 Character Key Shortcuts](https://www.w3.org/WAI/WCAG21/Understanding/character-key-shortcuts.html)167- [W3C UI Events KeyboardEvent key Values](https://www.w3.org/TR/uievents-key/)168- [Apple HIG - Keyboards](https://developer.apple.com/design/human-interface-guidelines/keyboards)169- [macOS Keyboard Shortcuts](https://support.apple.com/en-us/102650)170- [Windows Keyboard Accessibility](https://learn.microsoft.com/en-us/windows/apps/design/accessibility/keyboard-accessibility)171172### デファクト参照173- [GitHub Keyboard Shortcuts](https://docs.github.com/en/get-started/accessibility/keyboard-shortcuts)174- [Gmail Keyboard Shortcuts](https://support.google.com/mail/answer/6594)175- [Slack Keyboard Shortcuts](https://slack.com/help/articles/201374536-Slack-keyboard-shortcuts)176- [VS Code Keybindings](https://code.visualstudio.com/docs/configure/keybindings)