ダイアログ

モーダル ダイアログは、ウェブページ上の特別なタイプのポップアップ ボックスで、ユーザーが自身に集中するように促すポップアップです。有効なダイアログをポップアップするユースケースもいくつかありますが、その前に慎重に検討する必要があります。モーダル ダイアログでは、ユーザーに特定のコンテンツへの注意を強いられ、一時的にページの残りの部分は無視されます。

ダイアログは、モーダル(ダイアログ内のコンテンツのみが操作可能)または非モーダル(ダイアログ外のコンテンツを操作可能)のいずれかにできます。モーダル ダイアログは、ページ コンテンツの残りの部分に表示されます。ページの残りの部分は inert であり、デフォルトでは半透明の背景によって隠されます。

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

モーダル <dialog> の例を次に示します。[モーダル ダイアログを開く] ボタンでダイアログを開きます。開いた後にダイアログを閉じるには、Esc キー、formmethod="dialog" が設定されているボタン(またはフォーム自体に method="dialog" が設定されている場合)および HTMLDialogElement.close() メソッドの 3 つの方法があります。

HTMLDialogElement には、3 つの主要なメソッドと、HTMLElement から継承されるすべてのメソッドがあります。

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 属性を設定すると、ダイアログが開いたときにフォーカスが取得されます。ただし、<dialog> 内に autofocus を含める場合は、十分な注意が必要です。自動的にフォーカスされた要素の前のシーケンス内の要素はすべてスキップされます。 この属性については、フォーカス レッスンで詳しく説明します。

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 プロパティを使用。
もう一度お試しください。