Dialog

ダイアログ要素は、HTML であらゆる種類のダイアログを表すのに便利な要素です。その仕組みについて説明します。

モーダル ダイアログとは、ウェブページ上のポップアップ ボックスの一種で、ユーザーの操作を中断して自身にフォーカスを当てます。ダイアログをポップアップ表示する正当なユースケースもありますが、実行する前に十分な検討が必要です。モーダル ダイアログは、ユーザーに特定のコンテンツに集中させ、少なくとも一時的にページの残りの部分を無視させます。

ダイアログは、モーダル(ダイアログ内のコンテンツのみを操作できる)または非モーダル(ダイアログ外のコンテンツも操作できる)のいずれかになります。モーダル ダイアログは、ページ コンテンツの最上部に表示されます。ページの残りの部分は非アクティブになり、デフォルトでは半透明の背景で隠されます。

ダイアログを作成するためのセマンティック HTML <dialog> 要素には、セマンティクス、キーボード操作、HTMLDialogElement インターフェースのすべてのプロパティとメソッドが付属しています。

以下に、モーダル <dialog> の例を示します。[Open modal dialog] ボタンでダイアログを開きます。開いたダイアログを閉じるには、Escape キーを押す、formmethod="dialog" が設定されたボタンでフォームを送信する(またはフォーム自体に method="dialog" が設定されている場合)、HTMLDialogElement.close() メソッドを使用する、という 3 つの方法があります。

HTMLDialogElement には、HTMLElement から継承されたすべてのメソッドに加えて、3 つのメイン メソッドがあります。

dialog.show() /* opens the dialog */
dialog.showModal() /* opens the dialog as a modal */
dialog.close() /* closes the dialog */

この <dialog>HTMLDialogElement.showModal() メソッドで開かれたため、モーダル ダイアログです。モーダル ダイアログを開くと、ダイアログ自体以外のすべてのものが非アクティブになり、隠されます。ダイアログの外側の UI にカーソルを合わせると、すべての要素が pointer-events: none; が設定されているかのように動作していることがわかります。ダイアログを開くボタンでさえ、操作に反応しません。

ダイアログが開くと、フォーカスがダイアログ内に移動します。フォーカスは、そのダイアログ内の順次キーボード ナビゲーション順序の最初の要素に設定されます。tab キーを繰り返し押すと、モーダル ダイアログが開いている間は、ダイアログ内のコンテンツのみにフォーカスが移動します。モーダル ダイアログが開いている間は、ダイアログの外側のすべての要素が操作不能になります。

ダイアログが閉じられると、モーダルであるかどうかにかかわらず、フォーカスはダイアログを開いた要素に戻ります。ユーザー アクションなしでダイアログをプログラムで開くことは避けてください。ダイアログを開く前のフォーカス位置に戻す必要がある場合は、特にユーザーがダイアログを操作せずに閉じた場合に、フォーカス位置が戻るようにしてください。

アクティブなダイアログ以外の要素とそのすべての子孫を無効にするために使用できるグローバル inert 属性があります。showModal() を使用してモーダル ダイアログを開くと、不活性化または無効化が伴います。属性は明示的に設定されません。

ダイアログ以外のすべてを覆い隠す背景は、::backdrop 疑似要素を使用してスタイルを設定できます。背景は、.showModal() メソッドで <dialog> が表示される場合にのみ表示されます。この疑似要素は、FullScreen API が使用されているときに表示されるものなど、すべての背景と一致します。たとえば、画面やモニターと同じアスペクト比ではない動画を全画面モードで視聴している場合などです。

モードレス ダイアログ

同様に、HTMLDialogElement.show() はダイアログを開きますが、背景を追加したり、何かを不活性にしたりすることはありません。Esc キーを押しても、非モーダル ダイアログは閉じません。そのため、非モーダル ダイアログを閉じる方法を含めることがさらに重要になります。その際、閉じるボタンがダイアログの外にある場合、フォーカスはダイアログを開いた要素に移動します。これはユーザー エクスペリエンスの観点から最適ではない可能性があります。

ダイアログを閉じるボタンは仕様で正式に必須とされていませんが、必須と見なしてください。Esc キーを押すと、モーダル ダイアログは閉じますが、非モーダル ダイアログは閉じません。フォーカスを受け取ることができる可視ボタンは、アクセシビリティとユーザー エクスペリエンスを向上させます。

ダイアログを閉じる

ダイアログを閉じるために HTMLDialogElement.close() メソッドは必要ありません。JavaScript はまったく必要ありません。JavaScript を使用せずに <dialog> を閉じるには、<form>method="dialog" を設定するか、ボタンに formmethod="dialog" を設定して、ダイアログ メソッドを含むフォームを含めます。

ユーザーが dialog メソッドで送信すると、ユーザーが入力したデータの状態が維持されます。送信イベントはありますが、フォームは制約の検証を受け(novalidate が設定されていない場合)、ユーザーデータはクリアも送信もされません。JavaScript を使用しない閉じるボタンは次のように記述できます。

<dialog open>
  <form method="dialog">
    <button type="submit" autofocus>close</button>
  </form>
</dialog>

この例では、閉じタグ <button>autofocus 属性が設定されています。<dialog> 内で autofocus 属性が設定されている要素は、ページ読み込み時にフォーカスを受け取りません(ダイアログが表示された状態でページが読み込まれた場合を除く)。ただし、ダイアログが開くとフォーカスが移動します。

デフォルトでは、ダイアログが開くと、ダイアログ内の別の要素に autofocus 属性が設定されていない限り、ダイアログ内の最初のフォーカス可能な要素がフォーカスを受け取ります。閉じるボタンに autofocus 属性を設定すると、ダイアログが開いたときにフォーカスが確実に移動します。ただし、autofocus<dialog> 内に含める場合は、慎重に検討する必要があります。自動フォーカスされた要素の前にシーケンス内のすべての要素がスキップされます。この属性については、フォーカス レッスンで詳しく説明します。

HTMLDialogElement インターフェースには、returnValue プロパティが含まれています。method="dialog" を含むフォームを送信すると、returnValue は、フォームの送信に使用された送信ボタンの name(存在する場合)に設定されます。<button type="submit" name="toasty">close</button> と記述した場合、returnValuetoasty になります。

ダイアログが開くと、ブール値の open 属性が存在します。これは、ダイアログがアクティブで操作可能であることを意味します。.show() または .showModal() ではなく open 属性を追加してダイアログを開くと、ダイアログはモーダルレスになります。HTMLDialogElement.open プロパティは、ダイアログがモーダルかどうかではなく、インタラクションに使用できるかどうかによって true または false を返します。

JavaScript はダイアログを開くための推奨される方法ですが、ページの読み込み時に open 属性を含め、.close() で削除することで、JavaScript が使用できない場合でもダイアログを利用できるようにすることができます。

補足情報

tabindex を使用しない

ダイアログを開くために有効化された要素と、その中に含まれる閉じるボタン(およびその他のコンテンツ)は、フォーカスを受け取ることができ、インタラクティブです。<dialog> 要素はインタラクティブではなく、フォーカスを受け取りません。ダイアログ自体に tabindex プロパティを追加しないでください。

ARIA ロール

暗黙的なロールは dialog です。ダイアログが、確認やその他のユーザーの応答が必要な重要なメッセージを伝える確認ウィンドウである場合は、role="alertdialog" を設定します。ダイアログにもユーザー補助機能名が必要です。表示されるテキストでユーザー補助機能用の名前を指定できる場合は、aria-labelledby="idOfLabelingText" を追加します。

CSS のデフォルト

ブラウザでは dialog のデフォルトのスタイルが提供されます。Firefox、Chrome、Edge はユーザー エージェント スタイルシートで color: CanvasText; background-color: Canvas; を設定し、Safari は color: black; background-color: white; を設定します。colordialog から継承され、body:root からは継承されません。これは想定外の動作である可能性があります。background-color プロパティは継承されません。

理解度を確認する

ダイアログ要素に関する知識をテストします。

ダイアログの背後の領域のスタイルを設定するにはどうすればよいですか?

::background 疑似要素を使用します。
もう一度お試しください。
::backdrop 疑似要素を使用します。
正解です。
background プロパティを使用します。
もう一度お試しください。