本文へスキップ

フォーカストラップ

<dialog>.showModal() で開き、背後のページに inert を付けて Tab も読み上げも届かなくする。Tab は中で循環し、閉じると開いたボタンへフォーカスが戻る。

ENGLISH

Focus Trap (dialog + inert)

  • JS
143基本のUI部品 / アクセシブルUI の一覧 →

プレビュー

クリック

操作クリック/タップで動きます。

デザインの要点

  • 背後は aria-hidden ではなく inert にする。aria-hidden は読み上げだけ隠し、Tab では到達できてしまう
  • 開いたら最初の入力欄へ、閉じたら開いたボタンへフォーカスを戻す。戻さないと文書の先頭に飛び、位置を見失う
  • Tab の循環は最後→最初・Shift+Tab の最初→最後の2箇所だけ書けばよい。それ以外はブラウザに任せる
  • Esc・キャンセル・背景クリックのどれでも閉じられるようにする。閉じ方が1つしか無いダイアログは牢屋になる

コード(コピーして使えます)

<div class="ftd-stage">
  <div class="ftd-page" id="ftd-page">
    <p class="ftd-h">プロジェクト「春の展示会」</p>
    <div class="ftd-actions">
      <button type="button" id="ftd-open" class="ftd-primary">メンバーを招待</button>
      <button type="button" class="ftd-ghost">設定</button>
      <a href="#ftd-help" class="ftd-link">ヘルプ</a>
    </div>
    <p class="ftd-note">ダイアログが開いている間、このボタンやリンクは inert(Tab でも読み上げでも到達できない)</p>
  </div>
  <dialog class="ftd-dialog" id="ftd-dialog" aria-labelledby="ftd-title">
    <form method="dialog" class="ftd-form">
      <h2 id="ftd-title">メンバーを招待</h2>
      <label class="ftd-field">メールアドレス<input type="email" id="ftd-email" placeholder="name@example.com" autocomplete="off"></label>
      <div class="ftd-foot">
        <button type="button" id="ftd-cancel" class="ftd-ghost">キャンセル</button>
        <button type="submit" class="ftd-primary">招待を送る</button>
      </div>
      <p class="ftd-order"><span class="ftd-tag">Tab の順</span><span id="ftd-order">メール → キャンセル → 招待を送る → メール…</span></p>
    </form>
  </dialog>
  <div class="ftd-band"><span class="ftd-tag">フォーカス</span><span id="ftd-msg">閉じている: 背後のボタンは操作できる</span></div>
</div>

タグ

同じカテゴリ「アクセシブルUI」のほかのパーツ

関連パーツ