開閉・展開

ディスクロージャー(開閉)

解説あり

Disclosure

「もっと見る」のように1つの領域を表示/非表示するもっともシンプルな開閉パターン。

ディスクロージャー(開閉)とは?

ディスクロージャーは、1つのボタンを押すと、その下の1つの領域が 開いたり閉じたりする、もっともシンプルな開閉 UI です。 「もっと見る」「詳細を表示」「FAQ の答えを開く」などでよく使われます。

アコーディオンが「複数の見出し+複数のパネル」をまとめたものなのに対し、 ディスクロージャーはボタン1つ・領域1つの最小単位だと考えると分かりやすいです。

なぜアクセシビリティが大事なの?

見た目だけ作ると、次の人たちが取り残されます。

解決策はシンプルです。トリガーを <button> にして、aria-expanded で開閉状態を伝えるだけです。

ライブデモ(推奨実装)

下の「もっと見る」ボタンは APG に沿った実装です。マウスを使わず、キーボードだけで操作してみてください。

アクセシブルなディスクロージャー

アクセシビリティとは、年齢や障害の有無にかかわらず、 誰もが情報やサービスを利用できるようにする考え方です。

試してみよう:Tab でボタンに移動 → Enter / Space で開閉。ラベルが「もっと見る」⇄「閉じる」に変わります。

ポイント

スクリーンリーダー(macOSなら +F5 で VoiceOver)をオンにすると、 ボタンにフォーカスしたとき「もっと見る, 折りたたみ, 展開済み」のように役割と状態が読み上げられます。これが aria-expanded の効果です。

キーボード操作

キー動作必須/任意
Enter / Space領域を開く / 閉じる必須
Tab次 / 前のフォーカス可能要素へ移動必須

補足

EnterSpace での開閉は、トリガーを <button> にするだけで自動的に得られます。自分でキー処理を書く必要はありません。これがネイティブ要素の強みです。

必要な WAI-ARIA / ロール

付ける場所属性 / ロール意味
トリガー<button type="button">押せる要素にする。フォーカス・Enter/Space・「ボタン」ロールが自動で付く。
トリガーaria-expanded="true | false"領域が開いているか。状態の変化に合わせて必ず更新する。
トリガーaria-controls="領域のid"どの領域を制御するボタンかを示す。
閉じている領域hidden閉じている間はDOMから隠し、キーボード/読み上げの対象外にする。

実装:推奨パターン(Good)

良い例 / 推奨

トリガーを <button> にし、aria-expanded を状態と同期させます。

マークアップ:

<button type="button"
        id="more-btn"
        aria-expanded="false"
        aria-controls="more-region">
  もっと見る
</button>

<div id="more-region" hidden>
  <p>ここに隠していた詳しい説明が入ります。</p>
</div>

開閉のスクリプト(状態の同期がすべて):

const trigger = document.getElementById('more-btn');
const region = document.getElementById('more-region');

if (trigger && region) {
  trigger.addEventListener('click', () => {
    const expanded = trigger.getAttribute('aria-expanded') === 'true';
    // 状態を反転して aria-expanded と表示・ラベルを同期させる
    trigger.setAttribute('aria-expanded', String(!expanded));
    region.hidden = expanded;
    trigger.textContent = expanded ? 'もっと見る' : '閉じる';
  });
}

補足

ボタンのラベルを「もっと見る」⇄「閉じる」のように切り替えると、 晴眼のユーザーにも次の動作が伝わって親切です。aria-expanded の更新は必ず行ってください(見た目だけ変えても支援技術には伝わりません)。

アンチパターン(Bad)

下は <div>onclick だけで作った「見た目だけ同じ」開閉です。マウスでは開けますが、キーボードでは一切操作できません。上のデモと同じように TabEnter を試して、違いを体感してください。

div で作った壊れたディスクロージャー

アクセシビリティとは、年齢や障害の有無にかかわらず、 誰もが情報やサービスを利用できるようにする考え方です。

もっと見る +

試してみよう:Tab を押しても「もっと見る」にフォーカスが当たりません。スクリーンリーダーでは「ボタン」とも認識されず、開閉できることすら伝わりません。

<!-- ❌ アンチパターン -->
<!-- div なのでキーボードでフォーカスできず、ボタンとも認識されない -->
<div class="more" onclick="toggle()">もっと見る +</div>

<div id="more" style="display:none">
  <p>ここに隠していた詳しい説明が入ります。</p>
</div>

悪い例 / 避ける

この実装の問題点:

  • キーボードで操作できないdiv はフォーカスを受け取れない。
  • 役割が伝わらない — スクリーンリーダーには「ただのテキスト」に聞こえ、押せると分からない。
  • 状態が伝わらないaria-expanded がなく、開/閉が判別できない。
  • display:none のインラインstyle頼みで、hidden 属性や状態管理が無い。

ポイント

どうしても <div> を使うなら、role="button"tabindex="0"Enter/Space のキー処理・aria-expandedすべて自前で足す必要があります。 最初から <button> を使えば、その大半がタダで手に入ります。

実装チェックリスト


原文(英語):Disclosure Pattern — W3C APG(新しいタブで開きます)