トピックを検索
Tabで閉じてフォーカスを見失う検索パネル
入力欄からフォーカスが外れた瞬間に閉じ、Escapeキーにも反応せず、フォーカスのある要素ごと隠してしまいます。
問題
キーボード利用者が検索結果に移動できず、Escapeキーで閉じられず、閉じると現在位置を見失います。
ショップのヘッダーに「検索」ボタンがあります。押すと下にパネルが開き、検索欄、いくつかの検索結果、閉じるボタンが並びます。「ランプ」と入力し、Tabキーで最初の結果へ進もうとすると、パネルが消え、フォーカスも一緒に消えます。もう一度開いてEscapeキーを押しても、何も起きません。次にTabキーを押すと、利用者が選んでいない位置から移動が始まります。
入力欄の blur で、フォーカスが外れるたびにパネルを閉じています。同じパネル内の結果へ移る場合も例外ではありません。フォーカスを持った結果が隠されるため、ブラウザーはフォーカスをページに戻します。結果にキーボードで届かず(2.1.1)、フォーカスが利用者の操作の流れから外れ(2.4.3)、検索ボタンはパネルが開いているかどうかを伝えません(4.1.2)。
キーボード、スクリーンリーダー、スイッチの利用者は、検索語を入力できても結果を選べません。パネルが閉じると、ページの先頭から現在位置を探し直すことになります。マウスでは入力欄からフォーカスが外れる前に結果をクリックできるため、長く気づかれないことがあります。
マークアップは名前のあるボタン、ラベル付きの入力欄、通常のリンクなので、静的なチェックでは問題が見つかりません。問題が出るのは、パネルを開いた後にフォーカスを動かしたときだけです。「外をクリックしたらドロップダウンを閉じる」ための方法として blur はよく紹介され、AIのコーディングツールも、フォーカスの行き先を確かめずに同じコードを書きます。
試してみる
検索を開いて入力し、Tabで検索結果へ進んでください。
二つのランプと閉じるボタンに届きますか?Escapeも試して、フォーカスがどこに残るか見てください。
問題あり 直してみませんか?
フォーカス: –
再現デモです。「問題あり」は意図的にアクセシブルでない状態にしています。
修正方法
利用者が閉じたときか、部品全体から出たときだけ閉じ、自分で閉じたときは開いたボタンにフォーカスを戻します。
- 1パネル内でフォーカスを動かしても閉じない。
- 2Escapeキーと名前のある閉じるボタンで閉じ、開いたボタンにフォーカスを戻す。
- 3開くボタンが、パネルが開いているかどうかを伝える。
<button type="button" id="search-trigger">検索</button><div id="search-panel" hidden> <label for="search-input">商品を検索</label> <input id="search-input" type="search"> <ul> <li><a href="/lamps/arc">アーチ型フロアランプ</a></li> <li><a href="/lamps/dome">ドーム型テーブルランプ</a></li> </ul> <button type="button" id="search-close">閉じる</button></div><button type="button">カート</button>入力欄からTabキーで移動すると、結果を使う前にパネルが閉じます。閉じるボタンにはまったく届きません。Escapeキーの処理も、フォーカスを戻す処理もなく、ボタンには開閉状態がありません。
パネルはマークアップ上でボタンの直後にあるため、Tabキーはボタン、入力欄、結果、閉じるボタン、カートの順に進みます。部品の中でフォーカスを動かしてもパネルは閉じません。Escapeキーと「検索を閉じる」のどちらでも閉じ、フォーカスは「検索」に戻ります。「検索」ボタンは開閉状態を伝えます。TabやShift + Tabで部品の外へ出たときは、フォーカスを動かさずに閉じます。パネルの tabindex="-1" によって、パネルの空いた部分をクリックしてもフォーカスが内側に残り、閉じずに済みます。
どちらも基準を満たします。スクリプトの開閉パネルはすべてのブラウザーで動き、ページのレイアウトの中に置け、フォーカスが外れたときに閉じることもできますが、すべて自分で保守するコードです。popoverはスクリプトが不要で、Escapeキー、開閉状態、フォーカスの戻りをブラウザーが扱います。最上位レイヤーに表示されるため位置は自分で決める必要があり(CSSのアンカー配置か数行のスクリプト)、Tabで離れても開いたままです。対応ブラウザーがすべてpopoverに対応し、開いたまま残っても困らない場合はpopoverを選びます。フォーカスが外れたら閉じる必要がある場合や、最上位レイヤーではレイアウトが崩れる場合は、スクリプトの開閉パネルを選びます。
フォーカスが外れたら閉じるかどうかは、デザインの判断で、必須ではありません。Tabで離れた後にパネルが開いたままでも、フォーカスは外へ出ているため、キーボードトラップではありません。問題になるのは、フォーカスが中にあるのに閉じることと、出た後にフォーカスを中へ引き戻すことです。フォーカスが外れたら閉じる場合は、入力欄だけでなく、部品全体と relatedTarget を比べてください。
開いたボタンにフォーカスを戻すのは、Escapeキーや閉じるボタンで利用者が自分で閉じたときだけです。Tabで離れたときや、ほかの場所をクリックしたときは、利用者が移した位置にフォーカスを残します。type="search" の入力欄をEscapeキーで空にするブラウザーでは、1回目のEscapeで文字を消し、2回目で閉じる方法もあります。両方の操作を確認してください。
これはモーダルではないパネルです。フォーカスの閉じ込め、aria-modal、背後のinertは加えません。それらは modal-focus-management のガイドで扱っています。フォーカスを入力欄に置いたまま矢印キーで候補を選ぶ部品は、コンボボックスです。その場合は aria-activedescendant や結果の読み上げを含むコンボボックスのパターンに従ってください。閉じるボタンには文字で名前を付けます。×だけのボタンは icon-buttons のガイドを参照してください。
修正の確認
マウスを使わない5つの確認
確認方法: キーボード、スクリーンリーダー
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。共通のヘッダーや検索コンポーネントを変更した際は、再度確認します。
制限
これはモーダルではない検索パネルの出発点となる実装例で、コンボボックス、メニュー、ダイアログには当てはまりません。結果の取得や読み上げの処理は省略しています。実際の結果一覧を含めて、使用する支援技術で操作全体を確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。