<dialog>: ダイアログ要素
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2022.
<dialog>
は HTML の要素で、モーダルまたは非モーダルダイアログボックスや、それ以外の消すことができるアラート、インスペクター、サブウィンドウなどのような対話的コンポーネントを表します。
HTML の <dialog>
要素は、モーダルダイアログボックスと非モーダルダイアログボックスのどちらを作成する時にも使用します。 モーダルダイアログボックスは、ページの他の部分との操作を中断し、非モーダルダイアログボックスは、ページの他の部分との操作を許可します。
<dialog>
要素を表示するには、JavaScript を使用して下さい。モーダルダイアログを表示するには .showModal()
メソッドを、非モーダルダイアログを表示するには .show()
メソッドを使用して下さい。ダイアログボックスは .close()
メソッドを使用するか、または <dialog>
要素内に含まれる <form>
フォームを送信する際に dialog
メソッドを使用して閉じることができます。モーダルダイアログは、Esc キーを押すことでも閉じることができます。
属性
この要素にはグローバル属性があります。
警告: tabindex
属性を <dialog>
要素で使用してはいけません。詳しく使用上の注意を参照してください。
open
-
ダイアログボックスがアクティブであり、操作できる状態であることを示します。
open
が設定されていない場合、ダイアログボックスはユーザーに表示されません。 ダイアログを表示するには、open
属性ではなく.show()
または.showModal()
メソッドを使用することが推奨されます。もし<dialog>
がopen
属性を使用して開かれた場合、そのダイアログは非モーダルになります。メモ: モーダルではないダイアログボックスの開いた状態と閉じた状態を切り替えるには、
open
属性の有無を切り替えることができますが、この手法は推奨されません。
使用上の注意
- HTML の
<form>
要素は、属性 method=「dialog」 を保有している場合、またはフォームを送信するボタンにformmethod="dialog"
が設定されている場合に、ダイアログボックスを閉じることができます。<dialog>
内の<form>
がdialog
メソッドで確定されると、ダイアログボックスが閉じられ、そのフォームコントロールの状態が保存されますが、送信はされません。また、returnValue
プロパティは、押されたボタンの値に設定されます。 - CSS の
::backdrop
擬似要素は、モーダルダイアログの背景をスタイル設定するために使用することができます。これは、HTMLDialogElement.showModal()
メソッドを使用してダイアログを表示した際に、<dialog>
要素の背後に表示されます。例えば、この擬似要素を使用して、モーダルダイアログの背後の無効なコンテンツをぼかしたり、暗くしたり、といった方法で分かりにくくすることができます。 autofocus
属性を、モーダルダイアログが開いた直後にユーザーが操作することが想定される要素に追加すべきです。他に即座の操作が想定される要素がない場合は、autofocus
をダイアログ内の[閉じる]ボタンに追加するか、ユーザーがクリック/アクティブにして閉じることが想定される場合はダイアログ自体に追加することをお勧めします。<dialog>
要素にtabindex
プロパティを追加しないでください。この要素は操作対象ではなく、フォーカスを受け取らないからです。ダイアログの内容は(ダイアログに含まれない閉じるボタンを含め)、フォーカスを受け取ることができ、操作対象となります。
アクセシビリティ
ダイアログを実装する際には、ユーザーのフォーカスを設定する場所として最も適切な場所を検討することが重要です。HTMLDialogElement.showModal()
を用いて <dialog>
を開いたとき、フォーカスは内部で最初のフォーカス可能な要素に設定されます。autofocus
属性を使用して初期フォーカスの配置を明確に示すと、特定のダイアログに対して最適な初期フォーカスの配置とみなされる要素に初期フォーカスが設定するのに役立ちます。ダイアログの初期フォーカスがどこに設定されるか常にわからない場合、特にダイアログのコンテンツが呼び出されたときに動的に描画される場合、必要であれば <dialog>
要素そのものにフォーカスを当てることが、初期フォーカスの配置として最適と判断されるかもしれません。
ユーザーがダイアログを閉じることができる機構を確実に用意してください。すべてのユーザーが確実にダイアログを閉じることができるようにする最も確実な方法は、閉じるための明確なボタンを記載することです。例えば、確認、キャンセル、閉じるなどのボタンが適切です。
既定では、showModal()
メソッドによって呼び出されたダイアログは、Esc によって閉じることができます。非モーダルダイアログでは、既定では Esc キーで閉じませんし、非モーダルダイアログが表すものによっては、この動作が望ましくない場合があります。キーボードの利用者は、Esc キーでモーダルダイアログを閉じることを期待します。この動作が実装され、維持されていることを確認してください。複数のモーダルダイアログが開いている場合、Esc は最後に示されたダイアログのみを閉じるようにします。<dialog>
を使用した場合、この動作はブラウザーによって提供されます。
ダイアログは他の要素を使用して作成することができますが、ネイティブの <dialog>
要素は、同様の目的で他の要素を使用する場合は再現しなければならないユーザビリティとアクセシビリティ機能を提供します。独自のダイアログ実装を作成する場合は、すべての期待される既定の動作に対応しており、適切なラベル付けの推奨事項に従うことを保証してください。
<dialog>
要素は、ARIA の role="dialog" 属性を使用した独自ダイアログと同じような形で、ブラウザーが提供します。<dialog>
要素が showModal()
メソッドで呼び出された場合、暗黙のうちに aria-modal="true" となり、一方 <dialog>
が show()
メソッド、または open
属性を使用して表示されたり <dialog>
の既定の display
を変更した場合は [aria-modal="false"]
として表示されます。モーダルダイアログを実装する際には、<dialog>
とそのコンテンツ以外は inert
属性を使って不活性化する必要があります。<dialog>
を HTMLDialogElement.showModal()
メソッドで使用した場合、この動作はブラウザーが提供します。
例
HTML のみのダイアログ
この例は、HTML のみを使用して、モーダルではないダイアログの作成方法を示しています。論理属性 open
が <dialog>
要素にあるため、ページが読み込まれるとダイアログが開いた状態で表示されます。 <form>
要素の method
属性が "dialog"
に設定されているため、ダイアログは[OK]ボタンをクリックすることで閉じることができます。 この場合、フォームを閉じるために JavaScript は必要ありません。
<dialog open>
<p>Greetings, one and all!</p>
<form method="dialog">
<button>OK</button>
</form>
</dialog>
結果
メモ: 出力結果をリセットするには、このページを再読み込みしてください。
このダイアログは、open
属性が存在するために最初に開かれます。open
属性を使用して表示されるダイアログは、モーダルではありません。[OK]をクリックすると、ダイアログは閉じられ、結果フレームは空になります。ダイアログが閉じられた後、それを再度開くための方法は提供されていません。このため、モーダルではないダイアログを表示するには、 HTMLDialogElement.show()
メソッドを使用するのが推奨されます。論理属性である open
を追加または削除することで、ダイアログの表示を切り替えることも可能ですが、推奨される方法ではありません。
モーダルダイアログの作成
この例では、グラデーションの背景を持つモーダルダイアログを示しています。.showModal()
メソッドは、[ダイアログを表示]ボタンが押された際に、モーダルダイアログを開くためのものです。ダイアログは、Esc キーを押すか、ダイアログ内の[閉じる]ボタンが押された際に close()
メソッドを使用することで閉じることができます。
ダイアログが開くと、既定では、ブラウザーはダイアログ内でフォーカス可能な最初の要素にフォーカスを当てます。この例では、 autofocus
属性が[閉じる]ボタンに適用されており、このボタンにダイアログが開いたときにフォーカスが当たります。これは、ダイアログが開いた直後にユーザーが対話すると想定される要素だからです。
HTML
<dialog>
<button autofocus>閉じる</button>
<p>このモーダルダイアログの背景はクールです!</p>
</dialog>
<button>ダイアログを表示</button>
CSS
ダイアログの背景は、::backdrop
擬似要素を使用してスタイル設定することができます。
::backdrop {
background-image: linear-gradient(
45deg,
magenta,
rebeccapurple,
dodgerblue,
green
);
opacity: 0.75;
}
JavaScript
ダイアログは、.showModal()
メソッドを使用してモーダルに開かれ、.close()
メソッドを使用して閉じられます。
const dialog = document.querySelector("dialog");
const showButton = document.querySelector("dialog + button");
const closeButton = document.querySelector("dialog button");
// [ダイアログを表示]ボタンでダイアログがモーダルに開く
showButton.addEventListener("click", () => {
dialog.showModal();
});
// [閉じる]ボタンでダイアログを閉じる
closeButton.addEventListener("click", () => {
dialog.close();
});
結果
モーダルダイアログが表示されると、存在する他のダイアログの上に表示されます。モーダルダイアログの外側にあるものはすべて無効となり、ダイアログ外での操作はブロックされます。ダイアログが開いている間は、ダイアログ自体を除いて、文書内の操作は不可能であることに注意してください。[ダイアログを表示]ボタンは、ほとんど不透明なダイアログの背景によってほとんど隠されてしまい、無効となります。
ダイアログからの返値を扱い
この例では、<dialog>
要素の returnValue
と、フォームを使用してモーダルダイアログを閉じる方法を示しています。 既定では、returnValue
は空文字列、または <dialog>
要素内にフォームを送信するボタンがある場合はその値となります。
この例では、[ダイアログを表示]ボタンが押されるとモーダルダイアログが開きます。ダイアログには、<select>
と 2 つの <button>
要素という形でフォームが含まれており、既定では type="submit"
となっています。イベントリスナーは、選択オプションが変更された際に[確認]ボタンの値を更新します。[確認]ボタンがダイアログを閉じるために有効化された場合、ボタンの現在の値が返値となります。[キャンセル]ボタンが押されてダイアログが閉じられた場合、 returnValue
は cancel
となります。
ダイアログが閉じられると、返値が[ダイアログを表示]ボタンの下に表示されます。 Esc キーを押してダイアログが閉じられた場合、 returnValue
は更新されず、 close
イベントも発生しないため、<output>
内のテキストは更新されません。
HTML
<!-- フォームのあるモーダルダイアログ -->
<dialog id="favDialog">
<form>
<p>
<label>
好きな動物は?
<select>
<option value="default">選択してください…</option>
<option>ブラインシュリンプ</option>
<option>レッサーパンダ</option>
<option>クモザル</option>
</select>
</label>
</p>
<div>
<button value="cancel" formmethod="dialog">キャンセル</button>
<button id="confirmBtn" value="default">確認</button>
</div>
</form>
</dialog>
<p>
<button id="showDialog">ダイアログを表示</button>
</p>
<output></output>
JavaScript
const showButton = document.getElementById("showDialog");
const favDialog = document.getElementById("favDialog");
const outputBox = document.querySelector("output");
const selectEl = favDialog.querySelector("select");
const confirmBtn = favDialog.querySelector("#confirmBtn");
// "Show the dialog" ボタンで <dialog> をモーダルに開く
showButton.addEventListener("click", () => {
favDialog.showModal();
});
// "Cancel" ボタンで [formmethod="dialog"] による送信を行わずにダイアログを閉じ、close イベントを発行する
favDialog.addEventListener("close", (e) => {
outputBox.value =
favDialog.returnValue === "default"
? "No return value."
: `ReturnValue: ${favDialog.returnValue}`; // 空文字列ではなく、既定値かどうかを調べる必要がある
});
// [確認]ボタンが既定でフォームを送信しないようにし、`close()` メソッドでダイアログを閉じ、"close" イベントを発生させる
confirmBtn.addEventListener("click", (event) => {
event.preventDefault(); // この偽フォームを送信しない
favDialog.close(selectEl.value); // ここで選択ボックスの値を送る必要がある
});
結果
上記の例では、上記の例は、モーダルダイアログを閉じる次の 3 つのメソッドを示しています。
- ダイアログフォーム内のフォームを、
dialog
メソッドを使用して確定することによって(例えば、HTML のみの例を参照)。 - Esc キーを押すことよって。
HTMLDialogElement.close()
メソッドを呼び出すことによって(モーダルの例にあるように)。 この例では、[キャンセル]ボタンはダイアログフォームメソッドを介してダイアログを閉じ、[確認]ボタンはHTMLDialogElement.close()
メソッドを介してダイアログを閉じます。
[キャンセル]ボタンには formmethod="dialog"
が含まれており、 <form>
の既定の GET
メソッド (method
) を上書きします。フォームのメソッドが dialog
の場合、フォームの状態は送信されずに保存され、ダイアログは閉じられます。
action
がない場合、既定の GET
メソッドでフォームを送信すると、ページの再読み込みが発生します。JavaScript を使用して、送信を阻止し、ダイアログを閉じるために、それぞれ event.preventDefault()
と HTMLDialogElement.close()
メソッドを使用しています。
すべての dialog
要素で閉じるための仕組みを提供することが重要です。既定では、非モーダルのダイアログは Esc キーでは閉じませんし、ユーザーが物理キーボードにアクセスすることも想定してはいけません(たとえば、キーボードにアクセスできないタッチ画面端末を使用している人もいます)。
必須フォーム入力付きのダイアログを閉じる
ダイアログ内のフォームに必須入力項目がある場合、ユーザーエージェントは、必須入力項目に値が入力されるまで、ダイアログを閉じることができません。このようなダイアログを閉じるには、[閉じる]ボタンに formnovalidate
属性を使用するか、[閉じる]ボタンがクリックされたときにダイアログオブジェクトの close()
メソッドを呼び出すかしてください。
<dialog id="dialog">
<form method="dialog">
<p>
<label>
好きな動物は?
<input type="text" required />
</label>
</p>
<div>
<input type="submit" id="normal-close" value="通常 閉じる" />
<input
type="submit"
id="novalidate-close"
value="無検証 閉じる"
formnovalidate />
<input type="submit" id="js-close" value="JS 閉じる" />
</div>
</form>
</dialog>
<p>
<button id="show-dialog">ダイアログを表示</button>
</p>
<output></output>
JavaScript
const showBtn = document.getElementById("show-dialog");
const dialog = document.getElementById("dialog");
const jsCloseBtn = dialog.querySelector("#js-close");
showBtn.addEventListener("click", () => {
dialog.showModal();
});
jsCloseBtn.addEventListener("click", (e) => {
e.preventDefault();
dialog.close();
});
結果
出力から、[通常 閉じる]ボタンを使用してダイアログを閉じることができないことが分かります。しかし、[無検証 閉じる]ボタンの formnovalidate
属性を使用してフォームの検証をバイパスすれば、ダイアログを閉じることができます。プログラム上では、dialog.close()
を使用しても同様にダイアログを閉じることができます。
アニメーションするダイアログ
<dialog>
要素は、非表示時には display: none;
表示時には display: block;
と設定され、最上位レイヤーおよびアクセシビリティツリーから削除されたり、追加されたりします。したがって、 <dialog>
要素をアニメーションさせるには、 display
プロパティをアニメーション化する必要があります。対応ブラウザーでは、display
プロパティを離散的なアニメーション型で変化させてアニメーション化します。具体的には、ブラウザーは none
と他の display
値を交互に切り替えることで、アニメーション化されたコンテンツがアニメーションの全期間にわたって表示されるようにします。
例えば、
display
をnone
からblock
(あるいは他の可視のdisplay
値)にアニメーションする場合、アニメーション再生時間の0%
で値がblock
に切り替わり、常に表示されます。display
のblock
(または他の可視のdisplay
値)からnone
へのアニメーションでは、アニメーション再生時間の100%
の時点で値がnone
に切り替わるため、全体を通して表示されます。
メモ: CSS トランジションを使用してアニメーションを行う場合、上記の動作を有効にするには transition-behavior: allow-discrete
を設定する必要があります。CSS アニメーションでアニメーションを行う場合、この動作は既定では利用でき、同等の手順は必要ありません。
dialog 要素のトランジション
CSS トランジションで <dialog>
をアニメーションさせる場合、以下の機能が要求されます。
@starting-style
アットルール-
<dialog>
に設定されたプロパティの、開かれるたびにトランジションする開始値のセットを提供します。これは予期せぬ動作を避けるために必要です。既定では、CSS トランジションは、可視要素のプロパティが 1 つの値から別の値に変更された場合のみ発生します。要素の最初のスタイル更新時や、display
の型がnone
から別の型に変更された場合には発生しません。 display
プロパティ-
トランジションのリストに
display
を追加すると、トランジションの再生時間中、<dialog>
がdisplay: block
(またはダイアログが開いている状態として設定されている他の可視display
値)のままになり、他にもトランジションが確実に表示されます。 overlay
プロパティ-
トランジションのリストに
overlay
が含まれていると、最上位レイヤーから<dialog>
が確実に除去されるまでトランジションが完了するまで遅延され、トランジションが確実に表示されるようになります。 transition-behavior
プロパティ-
transition-behavior: allow-discrete
をdisplay
とoverlay
トランジション(またはtransition
一括指定)に設定すると、既定ではアニメーションできないこれら2つのプロパティで離散トランジションが有効になります。
この機能がどのようなものか見ていくために、例えば次のような例を挙げてみましょう。
HTML
この HTML は <dialog>
要素と、ダイアログを表示させるためのボタンを格納しています。さらに、<dialog>
要素には、それ自体を閉じさせるためのボタンがもう一つ格納されています。
<dialog id="dialog">
ここがコンテンツ
<button class="close">閉じる</button>
</dialog>
<button class="show">モーダル表示</button>
CSS
CSS では、@starting-style
ブロックを記述して、opacity
および transform
プロパティのトランジション開始時のスタイル、dialog[open]
状態のトランジション終了時のスタイル、<dialog>
が表示された後に元の状態に戻る際の既定の dialog
状態のスタイルを定義します。注意してほしいのは、 <dialog>
の transition
リストには、これらのプロパティだけでなく、display
と overlay
プロパティも含まれ、それぞれに allow-discrete
が設定されていることです。
また、開いたときに現れる <dialog>
の背後に現れる ::backdrop
の background-color
プロパティに開始時のスタイル値を設定し、素敵な暗転アニメーションを指定しました。 dialog[open]::backdrop
セレクターは、ダイアログが開いているときに、<dialog>
要素の背景のみを選択します。
/* 開いた状態のダイアログ */
dialog[open] {
opacity: 1;
transform: scaleY(1);
}
/* 閉じた状態のダイアログ */
dialog {
opacity: 0;
transform: scaleY(0);
transition:
opacity 0.7s ease-out,
transform 0.7s ease-out,
overlay 0.7s ease-out allow-discrete,
display 0.7s ease-out allow-discrete;
/* transition: all 0.7s allow-discrete;
と等しい*/
}
/* 開く前の状態 */
/* 詳細度が同じであるため、前の dialog[open] ルールの後に置かなければ効果がありません */
@starting-style {
dialog[open] {
opacity: 0;
transform: scaleY(0);
}
}
/* ダイアログがモーダルで最上位に来た場合に :backdrop をトランジションする */
dialog::backdrop {
background-color: rgb(0 0 0 / 0%);
transition:
display 0.7s allow-discrete,
overlay 0.7s allow-discrete,
background-color 0.7s;
/* transition: all 0.7s allow-discrete;
と等しい */
}
dialog[open]::backdrop {
background-color: rgb(0 0 0 / 25%);
}
/* この開始スタイル設定ルールは、上記のセレクター内にネストすることができません。
入れ子セレクターは擬似要素を表すことができないからです。 */
@starting-style {
dialog[open]::backdrop {
background-color: rgb(0 0 0 / 0%);
}
}
JavaScript
JavaScript で、表示ボタンと閉じるボタンにイベントハンドラーを追加し、クリックされたときに <dialog>
を表示させたり閉じたりするイベントを発生させます。
const dialogElem = document.getElementById("dialog");
const showBtn = document.querySelector(".show");
const closeBtn = document.querySelector(".close");
showBtn.addEventListener("click", () => {
dialogElem.showModal();
});
closeBtn.addEventListener("click", () => {
dialogElem.close();
});
結果
このコードは次のように表示されます。
メモ: <dialog>
は、表示される時点では常に display: none
から display: block
に変更されるため、項目遷移が発生するたびに、<dialog>
は @starting-style
スタイルから dialog[open]
スタイルにトランジションします。 <dialog>
が閉じられると、dialog[open]
状態から既定の dialog
状態にトランジションします。
このような場合、項目への入力時と出力時のスタイル設定のトランジションが異なることが可能です。この例については、「開始スタイルを使用する場合のデモ」をご覧ください。
dialog のキーフレームアニメーション
CSS のキーフレームアニメーションで <dialog>
をアニメーションさせる場合、トランジションとのいくつかの違いに注意する必要があります。
@starting-style
は提供しません。- キーフレームには
display
を記載します。これはアニメーション全体、または別のnone
以外の表示値が指定されるまでの表示値となります。 - 離散アニメーションを明示的に有効にする必要はありません。キーフレーム内に
allow-discrete
に相当するものはありません。 - また、キーフレーム内で
overlay
を設定する必要もありません。display
のアニメーションが<dialog>
の表示から非表示へのアニメーションを処理します。
この例を見て、どのようなものか見ていきましょう。
HTML
最初の HTML には、<dialog>
要素と、ダイアログを表示させるためのボタンがあります。さらに、<dialog>
要素には、それ自体を閉じるためのボタンが格納されています。
<dialog id="dialog">
ここがコンテンツです
<button class="close">閉じる</button>
</dialog>
<button class="show">モーダル表示</button>
CSS
CSSでは、<dialog>
を閉じられた状態と表示させた状態の間でアニメーションさせるためのキーフレームを定義し、さらに、<dialog>
の背景のフェードインアニメーションも定義しています。ダイアログボックスのアニメーションには、実際のアニメーション効果が再生時間全体にわたって確実に表示されるようにするための display
のアニメーションが含まれます。 バックグラウンドのフェードアウトのアニメーションは不可能であることに注意してください。背景は、ダイアログボックスが閉じられるとすぐに DOM から除去されるため、アニメーション化する何かがあるわけではありません。
dialog {
animation: fade-out 0.7s ease-out;
}
dialog[open] {
animation: fade-in 0.7s ease-out;
}
dialog[open]::backdrop {
animation: backdrop-fade-in 0.7s ease-out forwards;
}
/* Animation keyframes */
@keyframes fade-in {
0% {
opacity: 0;
transform: scaleY(0);
display: none;
}
100% {
opacity: 1;
transform: scaleY(1);
display: block;
}
}
@keyframes fade-out {
0% {
opacity: 1;
transform: scaleY(1);
display: block;
}
100% {
opacity: 0;
transform: scaleY(0);
display: none;
}
}
@keyframes backdrop-fade-in {
0% {
background-color: rgb(0 0 0 / 0%);
}
100% {
background-color: rgb(0 0 0 / 25%);
}
}
body,
button {
font-family: system-ui;
}
JavaScript
最後に、JavaScript でボタンにイベントハンドラーを追加し、<dialog>
を表示させたり閉じたりできるようにします。
const dialogElem = document.getElementById("dialog");
const showBtn = document.querySelector(".show");
const closeBtn = document.querySelector(".close");
showBtn.addEventListener("click", () => {
dialogElem.showModal();
});
closeBtn.addEventListener("click", () => {
dialogElem.close();
});
結果
このコードは次のように表示されます。
技術的概要
コンテンツカテゴリー | フローコンテンツ, 区分化ルート |
---|---|
許可されている内容 | フローコンテンツ |
タグの省略 | なし。開始タグと終了タグの両方が必須です。 |
許可されている親要素 | フローコンテンツを受け入れるあらゆる要素 |
暗黙の ARIA ロール | dialog |
許可された ARIA ロール | alertdialog |
DOM インターフェイス | HTMLDialogElement |
仕様書
Specification |
---|
HTML Standard # the-dialog-element |
ブラウザーの互換性
BCD tables only load in the browser
関連情報
HTMLDialogElement
インターフェイスclose
イベントcancel
イベントopen
プロパティ(HTMLDialogElement
インターフェイス)inert
グローバル属性(HTML 要素)- CSS の
::backdrop
擬似要素 - ウェブフォーム(学習領域)