この技術・考え方で達成できること
- 確実な回遊と脱出: マウスを使わなくても、TabキーとEnter/Spaceキーだけでサイトの全機能に到達でき、かつ途中で操作不能状態(トラップ)に陥らない
- 予測可能な移動順序: 画面上で「左から右、上から下」に見える順序と、実際にキーが移動する順序が一致しており、ユーザーが混乱せずに操作できる
- 入力の効率化: フォーム入力やデータ操作などのタスクを、手をキーボードから離さずに素早く完了できる
例: この対応は、スクリーンリーダーを利用する全盲のユーザー(恒常的な障害)だけでなく、手首を骨折してマウスが握れないユーザー(一時的な障害)や、「マウスを動かすスペースすら無い狭いカフェのテーブルで仕事をしている人(状況的な障害)」が、ストレスなく業務システムを操作できるかに直結します。
なぜ対応が難しいか(または後回しにされるか)
モダンなCSS(flex-direction: row-reverse; や Grid の order プロパティ)を使うと、「HTMLのDOMの順序」と「画面上の見た目の順序」を簡単に切り離すことができるからです。
エンジニアが「見た目のレイアウト」を合わせるためだけにDOMの順序を無視してCSSで強引に配置を並べ替えると、キーボードのフォーカス順序が「右下に行ったと思ったら、突然左上に飛んだ」というようにワープする、非常に使いづらいUIが生まれてしまいます。
また、リッチで複雑な自作の「ドロップダウン」や「モーダルダイアログ」をDIVタグで作った結果、裏側にフォーカスが抜け落ちてしまうという技術的見落としも頻出します。
実装で取り除ける障壁(バリア)
キーボードナビゲーションの実装において、以下のミスマッチ(障壁)を取り除く必要があります。
- 論理的順序の崩壊: 見た目と操作順序が一致せず、脳内マッピングがバグる状態。視覚的にUIを捉えているキーボードユーザーにとって致命的なストレスになります。
- キーボードトラップ(罠): Tabキーで特定のエリアに入ると、何度Tabを押してもそこから抜け出せなくなる状態。「サイトのリロード」しか解決策がなくなる最悪の罠です。
- 無駄なTabストップ: クリックできるだけで機能を持たない過剰な要素までフォーカスが当たり、目的のコンテンツに辿り着くまでに「Tabキーを50回打たなければならない」ような過酷な状態。
正しいマークアップパターン(Before/After)
❌ Before: 裏側にフォーカスが通ってしまうモーダル
画面中央に独自のモーダルポップアップを開いているが、Tabキーを押し続けると、黒い半透明の背景の後ろにある元のページのリンクにフォーカスが当たってしまい、見えないボタンを押せてしまう。
なぜ問題か: 視覚的には「モーダルの世界」に入っているのに、操作の次元(フォーカス)が「<span class="no-glossary">背景の世界」に残っている状態です。キーボードユーザーは画面外のどこにいるのか分からなくなり、完全に操作不能に陥ります。
✅ After: フォーカストラップと <dialog> 要素の活用
モーダル展開時は背景の要素に inert 属性を付与して無効化するか、HTML標準の <dialog> 要素 の showModal() メソッドを使用する。
なぜ改善されるか:
最新の標準機能である <dialog> (または適切なフォーカストラップ実装)を使うと、フォーカスは自動的にモーダル内だけに「閉じ込められ(Trap)」ます。これにより、ユーザーは安全に目の前のモーダルでのタスクに集中でき、ESCキーで直感的に元の場所に戻れるようになります。
意図の伝達(デザイナー × エンジニア)
❌ 巨大すぎるクリッカブルエリア問題
デザイナーの視点: 「この商品カードコンポーネントは、画像・タイトル・中身の説明・お気に入りボタンがバラバラに配置されているけど、ユーザーが押しやすいように『カード全体』を1つの巨大な <a> リンクで包んでほしい」
エンジニアの視点: 「カード全体を1つのリンクにすると、その中にある『お気に入りボタン』への論理的なフォーカスが破綻します(リンクの中にボタンを入れるのはHTMLの仕様違反です)」
なぜ衝突するか: マウスでの「クリックのしやすさ(面)」と、キーボードでの「フォーカスの論理構造(点)」が競合しているためです。
どう合意するか:
「フォーカスを受け取る要素(Tabストップ)は誰か?」というインタラクションルールをデザイン段階で決定します。
エンジニアからは「カード全体のクリックはJavaScriptで拾うか、タイトル部分のリンクをCSSの擬似要素(::after)で全体に広げる実装にし、DOMのTabストップとしては『タイトル』と『お気に入りボタン』の2つだけに整理しませんか?」と提案し、HTMLの仕様違反を回避しつつデザイナーの意図を汲み取ります。
実践チェックリスト
最低ライン(Must)
[ ] ページのすべてのインタラクティブな要素(リンク、ボタン、フォーム)へ、キーボード操作のTabキー(およびShift+Tab)のみで順次到達・操作できる [ ] キーボードトラップが存在しない(ある要素に入った後、Tab / Shift+Tab、または ESC / Enter 等のキーボード操作のみで必ず抜け出せる) [ ] フォーカスが移動する順序(DOMの順序)が、視覚的なレイアウトの意味や論理的な並びと一致している(CSSで視覚順序を破壊していない)
理想ライン(Better)
[ ] 繰り返されるナビゲーションメニューの前に、「メインコンテンツへスキップ」する隠しリンク(フォーカス時にのみ表示されるスキップリンク)を提供している
[ ] カスタムコンポーネント(タブパネルやカルーセル等)に対して、WAI-ARIAオーサリングプラクティス(APG)に準拠した矢印キーナビゲーションを実装している
[ ] 複雑なレイアウトにおいて、意図的にフォーカス順序を制御する必要がある場合のみ tabindex="0" を適正に活用している(tabindexに 1 以上の正の数を設定するアンチパターンは避ける)
まとめ
- この記事の本質: キーボードナビゲーションは、単なる「Tab移動の対応」ではなく、DOMと視覚レイアウトの論理構造を同期させる設計である。
- 誰のどんな課題を解決するか: マウスが使えないユーザーやパワーユーザーに対する「操作不能状態(キーボードトラップ)」や「順序がワープする混乱」。
- 実務での判断軸: 「マウスを使わず、一歩ずつキーボードを踏んでいくと、この画面はどういう『順番の物語』になっているか?」
- 次に学ぶべき知識: セマンティクスとWAI-ARIA(HTMLが持つ本来の意味と、それを補う魔法のタグの使い方)
目的別のおすすめ:
- TAB移動時にフォーカスが見えない問題を解決するなら → フォーカスインジケーター
- より堅牢なHTMLタグの選び方を学ぶなら → セマンティクスとWAI-ARIA
この原則を実装で見る
この原則が実装でどう形になるかを、GUNJO の部品で確かめられます。