モーダル ダイアログは、ウェブページ上の特別なタイプのポップアップ ボックスで、ユーザーが自身に集中するように促すポップアップです。有効なダイアログをポップアップするユースケースもいくつかありますが、その前に慎重に検討する必要があります。モーダル ダイアログでは、ユーザーに特定のコンテンツへの注意を強いられ、一時的にページの残りの部分は無視されます。
ダイアログは、モーダル(ダイアログ内のコンテンツのみが操作可能)または非モーダル(ダイアログ外のコンテンツを操作可能)のいずれかにできます。モーダル ダイアログは、ページ コンテンツの残りの部分に表示されます。ページの残りの部分は 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>
と記述すると、returnValue
は toasty
になります。
ダイアログが開いているときは、ブール値 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;
が設定されます。color
は dialog
から継承され、body
や :root
から継承されません。これは想定外である可能性があります。background-color
プロパティは継承されません。
理解度チェック
ダイアログ要素の知識をテストします。
ダイアログの背後にある領域のスタイルはどのように設定するのですか?
::background
疑似要素を使用した場合。::backdrop
疑似要素を使用した場合。background
プロパティを使用。