アクセシブルなモーダルライブラリが幾つかあります。
ブラウザの標準のConfirmダイアログは、それなりにアクセシブルだとは思いますが、標準だとデザインが微妙です。
独自にモーダルを作ると、フォーカス管理が面倒なためオープンソースとして作る動機になっているのかと思います。
アクセシビリティーを謳っているライブラリ、広く使われているライブラリ等ありますが、ブラウザの戻るクリック時にダイアログを表示とかはやってくれなかったので、いくつかサンプル実装を作ってみました。
結果を記載します。


外部仕様として考えること

外部仕様として考えるべきことについて、いくつか参考になる記事があり、その内容を記載します。

モーダルと非モーダルダイアログ: 用いるべき場合とそうでない場合 – U-Site

モーダルと非モーダルダイアログについての説明記事です。
それぞれ定義が記載されています。以下、引用します。

  • ダイアログ

    ダイアログ(=dialog。dialogueともいう)とは、2人の人の間で交わされる対話のことをさす。ユーザーインタフェースにおけるダイアログとは、システムとユーザーの間の「対話」であり、ユーザーへの情報や行動の要求であることが多い。

  • モーダル

    モーダルダイアログとは、メインコンテンツの上に表示されるダイアログで、ユーザーにインタラクションを要求する特別なモードにシステムを移行させるもののことである。このダイアログは、ユーザーがそのモーダルダイアログに明確にインタラクトするまで、メインコンテンツを無効にする。

  • 非モーダル

    非モーダル(モードレスともいう)なダイアログやウィンドウは、メインコンテンツを無効にしない。すなわち、ダイアログボックスが表示されても、ユーザーインタフェースの機能が変わることはない。

WAI-ARIA 1.2の抜粋

Accessible Rich Internet Applications (WAI-ARIA) 1.2 日本語訳 には、モーダルの持つ機能について以下のように記載されています。

  • モーダルダイアログを表示する場合、ユーザーが操作できるコンテンツをモーダルに限定する。

  • モーダル要素をする際に、フォーカスが明示的に別の場所に設定されない限り、支援技術は要素にナビゲートすべき。

  • 支援技術は、モーダル要素のコンテンツへのナビゲーションを制限してもよい。

  • インターフェイスがモーダル要素の子孫のみを用いて制御することができることを保証しなければならない。
    言い換えると、モーダルダイアログが閉じるボタンを持つ場合、ボタンはダイアログの子孫となるべきである。

モーダルウィンドウを考える — Website Usability Info

モーダルウィンドウの外部仕様に関する記事です。参考になりました。
印象深い文章を引用します。

モーダルウィンドウは、あるページを開いているというコンテキストを維持しつつ付加的にコンテンツの提示ができる利点がある反面、基本的なユーザビリティやアクセシビリティが欠落しているケースが多く見受けられます。

モーダルウィンドウのユーザビリティ問題でよく見られるのが、ブラウザの「戻る」ボタンを押してしまい、ユーザーの予測と異なったページに戻ってしまうことです。

そもそもモーダルウィンドウは、ウェブサイトにおける一般的なコンテンツ表示の変化 (ページ遷移) とは異なる特殊なインタラクションなので安易な採用はおすすめしません

ブラウザの<wbr>「戻る」<wbr>ボタンを<wbr>押してしまい、<wbr>ユーザーの<wbr>予測と<wbr>異なった<wbr>ページに<wbr>戻る ですが、後述するライブラリでも実現しているものはないように思われました。


戻るの動作がライブラリに実装されない理由

Support native “back” buttons on mobile as “cancel” triggers. · Issue #1814 · sweetalert2/sweetalert2 Sweetalert2に機能が実装されない理由の記載があったので、抜粋します。

  • モーダルライブラリはサイズの小さいライブラリが多く、このような小さなライブラリでHistory APIを使用するのはライブラリ実装が煩雑になる。

  • 定義上、モーダルはブラウザの履歴にエントリを追加しない。モーダルは、ページにオーバーレイするウィンドウであり、ユーザーの注意を引くようになっている。ブラウザの戻るでモーダルを閉じるのは、ブラウザの履歴ロジックを壊す事になる。

ただ、スマートフォンに限っては、ブラウザの戻るボタンが非常に押しやすい場所にあるので、ブラウザバックで、モーダルを閉じる動作を行ったほうがいいシュチュエーションがある気がします。
よくあるのは、以下のシュチュエーションかと思います。

  1. Google等の検索エンジンの検索結果画面からユーザーがサイトに流入する。

  2. サイト表示直後に、モーダルがポップアップ表示する。だいたい広告であることが多い。

  3. ポップアップの閉じ方がわからず、スマートフォンのブラウザの戻るボタンをクリックする。

  4. 検索エンジンの検索結果画面に戻る。


ライブラリが機能を持っていないとはいえ、実装したい人はいるようで以下の文書を見つけました。


JavaScript Modal Library

sorrycc/awesome-javascript: 🐢 A collection of awesome browser-side JavaScript libraries, resources and shiny things.記載されているライブラリが、全てアクセシビリティなモーダルなのかには少し疑問を持ちました。

JavaScript のアクセシビリティを考慮したモーダルダイアログとしてどのようなライブラリがあるのか、demoを触りながら調べてみたところ、以下が見つかりました。


アクセシビリティなモーダルダイアログの実装例

ライブラリを使わずに、モーダルを実装している実装例になります。
ライブラリをいくつも使いたくない場合、参考に実装するのが良いかと思います。


BackSpaceキーと、ブラウザの戻るに反応するモーダルのサンプル

ライブラリを使って、モーダルダイアログのサンプルを作成しました。
各ライブラリのサンプルにBackSpaceキークリック時、モーダルを閉じる、ブラウザの戻るボタンクリック時に確認ダイアログを表示する実装を追加しています。

実装内容の補足説明

実装内容の補足説明を記載します。

  • Sweetalert2
    • デフォルトではモーダルはkeydownイベントを検知しない。
      Sweetaltert2は、デフォルトではモーダル表示時に、keydownイベントを検知しません。
      モーダル表示時に、stopKeydownPropagation: false設定するとkeydownイベントを検知するようになります。
      function executeExample() {
          Swal.fire({
          title : 'The Internet?',
          text : 'That thing is still around?',
          icon: 'question',
          stopKeydownPropagation: false
          });
      }
      
  • Micromodal

    • モーダル表示を判定する関数がない。
      Mictomodalには、モーダル表示を判定する関数がありません。
      モーダルに特定のclass名が付与されるので、以下のようなモーダル表示判定関数を作成しました。
      MicroModal.isVisible = function() {
          return document.querySelector('.is-open') != null
      }   
      
  • van11y-accessible-modal-window-aria

    • モーダル表示を判定する関数がない。
      van11y-accessible-modal-window-ariaにも、モーダル表示を判定する関数がありません。
      モーダルに特定のid名が付与されるので、以下のようなモーダル表示判定関数を作成しました。
      function isVisible(){
          return document.querySelector('#js-modal') != null
      }    
      
    • モーダルを非表示にするための、関数がない
      van11y-accessible-modal-window-ariaにはモーダルを非表示にする関数がありません。
      Close ボタンにidが付与されているので、ボタンの要素を取得して、クリックするようにしました。
      document.querySelector('#js-modal-close').click();
      
  • a11y-dialog

    • モーダルを非表示にするための、関数がない
      van11y-accessible-modal-window-ariaにも、モーダル表示を判定する関数がありません。
      モーダル表示、非表示を検知するイベントリスナーがあるので、イベントリスナーでフラグを設定するようにしました。
      var isVisible = false;
      var targetDialog = null;
      (function () {
          document.addEventListener('DOMContentLoaded', function () {
          var dialogEl1 = document.getElementById('my-accessible-dialog1');
          var mainEl = document.getElementById('main');
          var dialog1 = new window.A11yDialog(dialogEl1, mainEl);
          dialog1.on('show', function (dialogEl, event) {
              // 表示を検知して、フラグをtrueにする
              isVisible = true;
              targetDialog = dialog1;
          });
          dialog1.on('hide', function (dialogEl, event) {
              // 非表示を検知して、フラグをfalseにする
              isVisible = false;
          });
      ...
      

実装して思ったこと

BackSpaceクリックを拾って、モーダルを閉じたいシュチュエーションはそれほどなさそうに思いました。
戻るイベントで、一旦確認ダイアログを表示するのは、場合によっては実装しておいた方が良い気がします。
ただ、確認ダイアログでキャンセルを押すと、Mac Chrome の場合、表示しているウィンドウからフォーカスが外れる動作をしていて、タブで反応せず、マウスをクリックしないと元のウィンドウにフォーカスが戻りませんでした。
この辺りのコントロールもできたらいいかと思います。


参考

以下、記事作成中に読んだ文章リンクです。

以上です。

コメント