モーダルダイアログのアクセシビリティについて

モーダルダイアログのアクセシビリティについて

#a11y
#accessibility
#dialog
#modal
#ui
#ux
2024-08-27

はじめに

Web で利用されるモーダルダイアログについて、その実装やアクセシビリティについて掘り下げ、それらの実装などについてまとめます。内容は著者の理解に基づいており、正確性を保証するものではありません。

詳しくは ARIA-APG を参照ください。

Modal Dialog ExampleModal Dialog Examplehttps://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/dialog/

細かい実装については次の記事がとても参考になります。

アクセシブルなモーダルダイアログの実装について考えるアクセシブルなモーダルダイアログの実装について考えるhttps://zenn.dev/yend724/articles/20220511-pc51v32llyzu8kws

また、dialog要素はすでに baseline 2020 に含まれているためdialog要素も使うことができますが、その構造や挙動についても確認するため、dialog要素を使わない場合を考えます。

Dialog element | Can I use... Support tables for HTML5, CSS3, etcDialog element | Can I use... Support tables for HTML5, CSS3, etchttps://caniuse.com/dialog

モーダルダイアログとは

Wkipedia でモーダルは

何らかのウィンドウの子ウィンドウとして生成されるサブ要素のうち、ユーザーがそれに対して適切に応答しない限り、制御を親ウィンドウに戻さないもの

とされています。

モーダル、ダイアログ、モーダルダイアログ、など様々な名前で呼ばれることもありますが、ここではそれらの違いを明確にせず、ダイアログと呼びます。

モーダルウィンドウ - Wikipediaモーダルウィンドウ - Wikipediahttps://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%BC%E3%83%80%E3%83%AB%E3%82%A6%E3%82%A3%E3%83%B3%E3%83%89%E3%82%A6

Dialogs vs. Modals: Is there a difference?Dialogs vs. Modals: Is there a difference?https://dev.to/iam_timsmith/dialogs-vs-modals-is-there-a-difference-210k#:~:text=A%20dialog%20still%20allows%20a,modal%20must%20be%20dealt%20with

要素

ダイアログを構成する基本的な要素です。構造の概略としては以下のようになります。

1- オーバーレイ
2  - コンテナ
3    - タイトル
4    - 説明
5    - コンテンツ

もしくは

1- オーバーレイ
2- コンテナ
3  - タイトル
4  - 説明
5  - コンテンツ

オーバーレイ

ダイアログの背景として用いられることが多いです。半透明の要素を全画面に表示し、ダイアログ以外のコンテンツを操作できないようにします。 この要素の階層構造はコンテナの親要素でも、兄弟要素でも良いようです。react-ariaARIA-APGではコンテナの親要素に設定しています。radix-uiでは兄弟要素に設定しています。

オーバーレイをクリックするとダイアログを閉じることができるようにする場合もあります。UI ライブラリなどではそのようなオプションが提供されていることがありますが、その微妙な挙動などは微妙に異なります。 例えば、 radix-uiでは押下時にダイアログを閉じるようになっていますが、react-ariaではクリックでダイアログを閉じるようになっています。

コンテナ

ダイアログの親要素です。

タイトル

ダイアログのタイトルです。h2が見出し要素として使われることが多いですが、推奨される定義は見つかりませんでした。

説明

ダイアログの説明です。必須ではありませんが、ダイアログの内容を説明する必要がある場合は設定します。

コンテンツ

ダイアログのコンテンツです。フォームやボタンなど、ユーザーが操作する要素が含まれます。 基本的にダイアログを閉じるアクションを持つ要素を含める必要があります。

機能

アクセシビリティやユーザビリティを向上させるために、いくつかの注意があります。

MUST: ダイアログが閉じた際に、開く前にフォーカスしていた要素にフォーカスを戻す

基本的にはトリガーした要素にフォーカスを戻します。

次のようにダイアログからダイアログを経由する場合は最初のダイアログ A を開いたトリガーボタン A にフォーカスを戻します。(ARIA-APG のdialog1,dialog3の例)

  1. トリガーボタン A からダイアログ A を開く
  2. ダイアログ A 内のトリガーボタン B でダイアログ B を開く(ダイアログ A を閉じる)
  3. ダイアログ B を閉じる

SHOULD: ダイアログ内の最初の要素にフォーカスする

最初のフォーカス可能要素がダイアログの下部にあり、フォーカスによってスクロールされてコンテンツが順序通りに見れなくなってしまう場合は、フォーカスさせる必要はありません。(ARIA-APG のdialog2の例)

もし、確認ダイアログのようなもので OK ボタンをユーザーが押すことが期待される場合は、OK ボタンにフォーカスさせることも考えられます。必ずしも最初の要素にフォーカスさせる必要はありません。(ARIA-APG のdialog3の例)

Modal Dialog ExampleModal Dialog Examplehttps://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/dialog/

キーボード操作

ダイアログ内でのキーボード操作についても考慮する必要があります。 Tab でフォーカスを移動可能ですが、ダイアログ内にロックされ、ループするような挙動になります。

Tab

Shift + Tab

Esc

WAI-ARIA

支援技術に対応してアクセシビリティを向上させるために、WAI-ARIA で仕様が定められています。

WAI-ARIA basics - Learn web development | MDNWAI-ARIA basics - Learn web development | MDNhttps://developer.mozilla.org/en-US/docs/Learn/Accessibility/WAI-ARIA_basics

基本的な構造は以下のようになります。

1<div class="overlay" aria-hidden="true"></div>
2<div
3  role="dialog"
4  aria-modal="true"
5  aria-labelledby="dialog-title"
6  aria-describedby="dialog-description"
7>
8  <h2 id="dialog-title">タイトル</h2>
9  <p id="dialog-description">説明</p>
10  <button>OK</button>
11  <button>キャンセル</button>
12</div>

MUST: role="dialog"

支援技術にダイアログであることを示します。

ARIA: dialog role - Accessibility | MDNARIA: dialog role - Accessibility | MDNhttps://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/dialog_role

他にもrole="alertdialog"などの類似要素があります。

ARIA: alertdialog role - Accessibility | MDNARIA: alertdialog role - Accessibility | MDNhttps://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/alertdialog_role

MUST: aria-modal="true"

支援技術にダイアログであることを示し、それ以外のコンテンツを不活性要素として扱います。 しかし、aria-modalをサポートしていないアクセシビリティサービスがあるようで、aria-hidden も適用した方が良いかもしれません。

aria-modal - Accessibility | MDNaria-modal - Accessibility | MDNhttps://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-modal

モーダルウィンドウのコンテナ要素に aria-modal 属性を適用する | Accessible & Usableモーダルウィンドウのコンテナ要素に aria-modal 属性を適用する | Accessible & Usablehttps://accessible-usable.net/2021/06/entry_210606.html

SHOULD: aria-hidden

ダイアログ以外のコンテンツを隠すために、ダイアログが表示されている間はダイアログ以外の要素にaria-hidden="true"を設定します。

aria-hidden - Accessibility | MDNaria-hidden - Accessibility | MDNhttps://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-hidden

MUST: aria-labelledby

ダイアログのタイトルを示すために、ダイアログの見出し要素の ID を指定します。

SHOULD: aria-describedby

ダイアログの説明を示すために、ダイアログの説明要素の ID を指定します。説明が省略できる場合は省略しても構いません。

おわりに

ユーザー体験を考える上で、Tab のフォーカス移動がダイアログの後ろのコンテンツに移動しないようにしたり、ダイアログを表示した際に適切な要素にフォーカスするなど、考えるべき点が多い要素です。 独自実装が可能な Web の世界で自前で作成する場合は、より一般的で標準化されたインタラクションを実現したいと思いました。

参考

Modal Dialog ExampleModal Dialog Examplehttps://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/dialog/

DialogDialoghttps://react-spectrum.adobe.com/react-aria/Dialog.html

Dialog – Radix PrimitivesDialog – Radix Primitiveshttps://www.radix-ui.com/primitives/docs/components/dialog

シェア