本文へ移動
ご相談

開閉状態が伝わらないアコーディオン

見出しをクリックすると内容が開きますが、ボタンであることや開閉状態が支援技術に伝わりません。

WCAG 4.1.2 確認方法 キーボードスクリーンリーダーズーム強制配色 エージェント向けMarkdown
問題あり 開いても、状態が伝わらない。
修正後 「展開」と読み上げられる。
同じ操作部品の、修正前と修正後。
01

問題

どの見出しが開閉でき、今開いているのかが、キーボードやスクリーンリーダーでは分かりません。

場面 クリックでは開くが、キー操作では開かない。 詳しく読む閉じる

FAQの見出しをクリックすると回答が開きますが、支援技術には普通のテキストとして伝わります。キーボードでは開閉できません。

確認できる問題 見出しが操作部品として振る舞い、状態を持たない。 詳しく読む閉じる

見出しが開閉の操作を受け付けるのに、ボタンの役割が設定されていません。開閉状態も伝わらず、閉じたパネル内のリンクにTabキーで移動できてしまう場合があります。

利用者への影響 キーボード利用者と、開閉状態を聞き取る人。 詳しく読む閉じる

どの見出しが操作可能か、開いているかがわかりません。非表示の要素にフォーカスが移ると、操作している場所が分からなくなります。

自動チェックとAIの限界 属性があっても、状態が常に一致するかは確認されない。 詳しく読む閉じる

属性不足は検出できても、すべての状態遷移で aria-expanded が一致し、非表示の子要素にフォーカスが入らないことまでは証明できません。開閉を繰り返して確認してください。

02

試してみる

TabとEnterで、回答を開いてください。

Tabキーで質問へ移動して開いてください。閉じた状態でTabを押し続けると、フォーカスは消えますか?

再現デモです。「問題あり」は意図的にアクセシブルでない状態にしています。

03

修正方法

detailsとsummaryを使うか、見出し内のbuttonで開閉状態を伝えます。

  1. 1aria-expandedを、実際の表示と常に一致させる。
  2. 2閉じたパネルは高さ0ではなく、hidden属性で隠す。
  3. 3ページの構造に合った見出しレベルを保つ。
修正前 クリックできる見出しと、高さを0にしたパネル
<h3 class="faq-q" onclick="toggle(this)">返金の流れは?</h3><div class="faq-a" style="height: 0; overflow: hidden">  <p>返金は5日以内に届きます。<a href="/refunds">返金ポリシー</a></p></div>
修正後 HTML標準の開閉要素
<details>  <summary>返金の流れは?</summary>  <p>返金は5日以内に届きます。<a href="/refunds">返金ポリシー</a></p></details>
修正後 独自のアコーディオン

html

<h3>  <button type="button" aria-expanded="false" aria-controls="faq-refunds">    返金の流れは?  </button></h3><div id="faq-refunds" hidden>  <p>返金は5日以内に届きます。<a href="/refunds">返金ポリシー</a></p></div>

js

for (const button of document.querySelectorAll('[aria-controls]')) {  button.addEventListener('click', () => {    const open = button.getAttribute('aria-expanded') === 'true';    button.setAttribute('aria-expanded', String(!open));    document.getElementById(button.getAttribute('aria-controls')).hidden = open;  });}
この修正で直る理由

見出しにはTabキーで移動できず、開閉状態も伝わりません。閉じたパネルは高さを0にしているだけなので、中のリンクが見えないままフォーカスを受け取ります。

単純な質問と回答なら、details と summary を使うと、スクリプトなしでキーボード操作、開閉状態の伝達、閉じた内容のTab順からの除外ができます。

デザイン上、細かな制御が必要な場合は、見出しの中にbutton要素を置き、その状態とパネルの表示を一致させます。

hidden 属性を付けると、閉じたパネルはTab順からも、スクリーンリーダーが読む範囲からも外れます。アニメーションを付ける場合も、高さを0にするだけでなく、最後に hidden が設定されるようにしてください。

実装の判断

見出しとアイコンは、一つの開閉ボタンにまとめます。detailsとsummaryを使う場合、通常は aria-expanded を追加する必要はありません。独自実装では、固定のIDと aria-controls でボタンとパネルを関連付け、複数のパネルを同時に開けるかを決めます。矢印キーへの対応は任意ですが、Tabキーで移動できることは必須です。

見出しレベルはページ全体の構造に合わせ、スクリーンリーダーの見出し移動でも質問として使えるようにします。

04

修正の確認

マウスを使わない5つの確認

5件中0件を確認済み

OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。共通のアコーディオンコンポーネントを変更した際は、再度確認します。

制限

このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。スクリプトは、アニメーションやリンクでの直接表示を含まない最小限の例です。実際に使用する支援技術で、操作全体を確認してください。

よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。

参考資料: www.w3.org

コードを更新しても、使いやすさを保つために

ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。

再テストの進め方