このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docs コミュニティーについてもっと知り、仲間になるにはこちらから。

View in English Always switch to English

HTML <dialog> ダイアログ要素

Baseline Widely available *

This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2022年3月.

* Some parts of this feature may have varying levels of support.

<dialog>HTML の要素で、モーダルまたは非モーダルダイアログボックスや、それ以外の消すことができるアラート、インスペクター、サブウィンドウなどのような対話的コンポーネントを表します。

属性

この要素にはグローバル属性があります。

警告: tabindex 属性を <dialog> 要素で使用してはいけません。詳しく追加メモを参照してください。

closedby

<dialog> 要素を閉じるために使用できるユーザー操作の種類を指定します。この属性は、ダイアログが閉じられる可能性のある 3 つの方法を区別します。

  • 「簡単な解除のユーザー操作」。ユーザーがダイアログの外側をクリックまたはタップすると、<dialog> が閉じられます。これは、「自動」状態のポップオーバーにおける「簡単な解除」動作 と同等です。
  • 「プラットフォーム固有のユーザー操作」。例えば、デスクトッププラットフォームでは Esc キーを押す操作、モバイルプラットフォームでは「戻る」または「閉じる」ジェスチャーなど。
  • 開発者が指定した機構(例:<button>click ハンドラーを設定し、そこで HTMLDialogElement.close() を呼び出したり、 <form> を送信したりする。

利用可能な値は次の通りです。

any

ダイアログは、3 つのいずれかの方法で閉じることができます。

closerequest

ダイアログは、プラットフォーム固有のユーザー操作または開発者が指定した機構で閉じることができます。

none

このダイアログは開発者が指定した機構でのみ閉じることができます。

<dialog> 要素に有効な closedby 値が指定されていない場合、

  • showModal() を使用して開かれた場合、値が "closerequest" であるかのように動作します。
  • それ以外の場合、値が "none" であるかのように動作します。
open

ダイアログボックスがアクティブであり、操作できる状態であることを示します。 open が設定されていない場合、ダイアログボックスはユーザーに表示されません。 ダイアログを表示するには、open 属性ではなく .show() または .showModal() メソッドを使用することが推奨されます。もし <dialog>open 属性を使用して開かれた場合、そのダイアログは非モーダルになります。

メモ: モーダルではないダイアログボックスの開いた状態と閉じた状態を切り替えるには、open 属性の有無を切り替えることができますが、この手法は推奨されません。詳しくは open を参照してください。

解説

HTML の <dialog> 要素は、モーダルダイアログボックスと非モーダルダイアログボックスのどちらを作成する時にも使用します。 モーダルダイアログボックスは他のUIの要素の操作をブロックし、ページの他の部分を不活性にしますが、非モーダルダイアログボックスでは引き続き、ページの他の部分を操作することができます。

ダイアログを JavaScript で制御

JavaScript で <dialog> 要素を表示させたり閉じたりすることができます。 showModal() メソッドを使用するとモーダルダイアログを表示され、show() メソッドを使用すると非モーダルダイアログを表示させることができます。ダイアログボックスは、close() メソッドを使用するか、dialog の method を使用して、<dialog> 要素内にある <form> を送信する際に閉じることができます。 モーダルダイアログは、Esc キーを押して閉じることもできます。

呼び出しコマンドを使用して作成されたモーダルダイアログ

モーダルダイアログは、呼び出しコマンド API の HTML 属性である commandfor および command を使用して、宣言的に開いたり閉じたりすることが可能です。これらは <button> 要素に設定できます。

command 属性は、<button> 要素がクリックされた際に送信される具体的なコマンドを設定するものであり、commandfor 属性は、対象となるダイアログの id を設定します。 ダイアログに送信されるコマンドは、"show-modal""close""request-close" です。

下記の HTML は、<button> 要素に属性を関連付け、クリックすると <dialog>idが "my-dialog" であるモーダルダイアログを開くようにする方法を示しています。

html
<button command="show-modal" commandfor="my-dialog">ダイアログを開く</button>

<dialog id="my-dialog">
  <p>このダイアログは、呼び出しコマンドを使用して開きました。</p>
  <button commandfor="my-dialog" command="close">閉じる</button>
</dialog>

ポップオーバーコマンドを使用した非モーダルダイアログ

非モーダルダイアログは、ポップオーバー API の HTML 属性、popovertarget および popovertargetaction を使用することで、宣言的に開いたり、閉じたり、トグル切り替えしたりすることができます。これらは <button> および <input> 要素で定義できます。

<dialog> は、popover 属性を追加して、ポップオーバーとして設定しなければなりません。 その後、ボタンや入力フィールドに popovertarget 属性を使用してターゲットとなるポップオーバーを示し、popovertargetaction 属性を使用して、ボタンがクリックされた際にポップオーバーで実行されるアクションを指定できます。 なお、ダイアログはポップオーバーであるため、非モーダルとなり、ダイアログの外側をクリックすることで閉じることができます。

次の HTML は、<button> 要素に属性を適用し、クリックすることで <dialog> 要素の id が "my-dialog" であるモーダルダイアログを表示したり非表示にしたりする方法を示しています。

html
<button popovertarget="my-dialog">ダイアログを開く</button>

<dialog id="my-dialog" popover>
  <p>このダイアログは、popovertargetaction 属性を使用して開きました。</p>
  <button popovertarget="my-dialog" popovertargetaction="hide">閉じる</button>
</dialog>

ポープオーバー API では、JavaScript で状態を取得したり設定したりするために使用できるプロパティも提供しています。

ダイアログを閉じる

すべての <dialog> 要素に閉じるための機構を提供し、物理キーボードを持たない可能性のある端末でも動作することを保証することが重要です。

ダイアログを閉じる方法は数多くあります。

CSS スタイル設定

<dialog> は(他の要素と同様に)要素名を使用して選択できます。また、:modal:open などの擬似クラスを使用して、その状態を指定することもできます。

CSS の ::backdrop 擬似要素を使用することで、HTMLDialogElement.showModal() メソッドを用いてダイアログを表示させた際に、<dialog> 要素の背後に表示されるモーダルダイアログの背景をスタイル設定することができます。 この擬似要素を使用すると、例えば、モーダルダイアログの背後にある不活性なコンテンツをぼかしたり、暗くしたり、その他の方法で目立たなくしたりすることができます。

追加メモ

  • HTML の <form> 要素は、属性 method="dialog" がついている場合、またはフォームを送信するボタンに formmethod="dialog" が設定されている場合に、ダイアログボックスを閉じることができます。 <dialog> 内の <form>dialog メソッドで確定されると、ダイアログボックスが閉じられ、そのフォームコントロールの状態が保存されますが、送信はされません。また、 returnValue プロパティは、押されたボタンの値に設定されます。
  • 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() メソッドで使用した場合、この動作はブラウザーが提供します。

呼び出しコマンド API の HTML 属性

この例では、呼び出しコマンド APIcommandfor および command 属性を使用して、モーダルダイアログを開いたり閉じたりする方法を示しています。

まず、<button> 要素を宣言し、command 属性を "show-modal" に、commandfor 属性を開くダイアログの id (my-dialog) に設定します。 次に、「閉じる」というラベルの付いた <button> が含まれている <dialog> 要素を宣言します。このボタンは、"close" コマンドを(同じ)ダイアログの id に送信します。

html
<button command="show-modal" commandfor="my-dialog">ダイアログを開く</button>

<dialog id="my-dialog">
  <p>このダイアログは、呼び出しコマンドを使用して開きました。</p>
  <button commandfor="my-dialog" command="close">閉じる</button>
</dialog>

結果

[ダイアログを開く]ボタンをクリックして、ダイアログを開いてください。 [閉じる]ボタンを選択するか、Esc キーを押すと、ダイアログを閉じることができます。

ポップオーバー API の HTML 属性

この例では、popoverpopovertargetpopovertargetaction といった ポップオーバー API の HTML 属性を使用して、非モーダルダイアログを開閉する方法を示しています。

<dialog> には popover 属性を追加することで、ポップオーバーとして機能するようになります。 この属性の値を指定していないため、デフォルト値の "auto" が使用されます。 これにより、「簡単に閉じる」動作が有効になり、ダイアログの外側をクリックするか、Esc キーを押すことでダイアログを閉じることができます。 代わりに popover="manual" を設定して[簡単に閉じる」動作を無効にすることもでできます。その場合、ダイアログは「閉じる]ボタンを使用して閉じなければなりません。

なお、ダイアログを開くための <button> に対して、popovertargetaction 属性を指定していません。 この場合は、そのデフォルト値が toggle であるため、この属性は必要ありません。これにより、ボタンがクリックされた際に、ダイアログの開閉状態が切り替わります。

html
<button popovertarget="my-dialog">ダイアログを開く</button>

<dialog id="my-dialog" popover>
  <p>このダイアログは、popovertargetaction 属性を使用して開きました。</p>
  <button popovertarget="my-dialog" popovertargetaction="hide">閉じる</button>
</dialog>

結果

[ダイアログを開く]ボタンをクリックして、ダイアログを開いてください。 [閉じる]ボタンを選択するか、Esc キーを押すと、ダイアログを閉じることができます。 また、このダイアログは非モーダルであるため、ダイアログの外側をクリックしても閉じることができます。

ダイアログの open 属性の使用

この例では、ページが読み込まれた時点で既に開いている、HTML のみの非モーダルダイアログを生成するために、<dialog> 要素に論理値の open 属性を設定する方法を示しています。

<form> 要素の method 属性が "dialog" に設定されているため、[OK]ボタンをクリックすることでダイアログを閉じることができます。 この場合、フォームを閉じるために JavaScript は必要ありません。

html
<dialog open>
  <p>みなさん、こんにちは!</p>
  <form method="dialog">
    <button>OK</button>
  </form>
</dialog>

結果

このダイアログは、open 属性が設定されているため、初期状態では開いており、非モーダルです。 「OK」をクリックした後、ダイアログが閉じられ、Result フレームは空の状態になります。

メモ: 出力結果をリセットするには、このページを再読み込みしてください。

ダイアログが閉じられた後、それを再度開くための方法は提供されていません。このため、モーダルではないダイアログを表示するには、 HTMLDialogElement.show() メソッドを使用するのが推奨されます。論理属性である open を追加または削除することで、ダイアログの表示を切り替えることも可能ですが、推奨される方法ではありません。

モーダルダイアログの作成

この例では、グラデーションの背景を持つモーダルダイアログを示しています。.showModal() メソッドは、[ダイアログを表示]ボタンが押された際に、モーダルダイアログを開くためのものです。ダイアログは、Esc キーを押すか、ダイアログ内の[閉じる]ボタンが押された際に close() メソッドを使用することで閉じることができます。

ダイアログが開くと、既定では、ブラウザーはダイアログ内でフォーカス可能な最初の要素にフォーカスを当てます。この例では、 autofocus 属性が[閉じる]ボタンに適用されており、このボタンにダイアログが開いたときにフォーカスが当たります。これは、ダイアログが開いた直後にユーザーが対話すると想定される要素だからです。

HTML

html
<dialog>
  <button autofocus>閉じる</button>
  <p>このモーダルダイアログの背景はクールです!</p>
</dialog>
<button>ダイアログを表示</button>

CSS

ダイアログの背景は、::backdrop 擬似要素を使用してスタイル設定することができます。

css
::backdrop {
  background-image: linear-gradient(
    45deg,
    magenta,
    rebeccapurple,
    dodgerblue,
    green
  );
  opacity: 0.75;
}

JavaScript

ダイアログは、.showModal() メソッドを使用してモーダルに開かれ、.close() または .requestClose() メソッドを使用して閉じられます。

js
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" となっています。イベントリスナーは、選択オプションが変更された際に[確認]ボタンの値を更新します。[確認]ボタンがダイアログを閉じるために有効化された場合、ボタンの現在の値が返値となります。[キャンセル]ボタンが押されてダイアログが閉じられた場合、 returnValuecancel となります。

ダイアログが閉じられると、返値が[ダイアログを表示]ボタンの下に表示されます。 Esc キーを押してダイアログが閉じられた場合、 returnValue は更新されず、 close イベントも発生しないため、<output> 内のテキストは更新されません。

HTML

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

このダイアログは、[ダイアログを表示]ボタンにイベントリスナーを設定することで開かれます。ボタンがクリックされると、HTMLDialogElement.showModal() が呼び出されます。

[キャンセル]ボタンがクリックされるとダイアログが閉じられます。これは、<button>formmethod="dialog" 属性が指定されているためです。 フォームのメソッドが dialog の場合、フォームの状態は保存されますが送信はされず、ダイアログが閉じられます(この属性は <form> のデフォルトである GET メソッドを上書きします)。 action がない場合、既定の GET メソッドでフォームを送信すると、ページの再読み込みが発生します。 JavaScript を使用して、送信を阻止し、ダイアログを閉じるために、それぞれ event.preventDefault()HTMLDialogElement.close() メソッドを使用しています。

js
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"
      ? "返値がありません。"
      : `ReturnValue: ${favDialog.returnValue}`; // 空文字列ではなく、既定値かどうかを調べる必要がある
});

// [確認]ボタンが既定でフォームを送信しないようにし、`close()` メソッドでダイアログを閉じ、"close" イベントを発生させる
confirmBtn.addEventListener("click", (event) => {
  event.preventDefault(); // この偽フォームを送信しない
  favDialog.close(selectEl.value); // ここで選択ボックスの値を送る必要がある
});

結果

必須フォーム入力付きのダイアログを閉じる

ダイアログ内のフォームに必須入力項目がある場合、ユーザーエージェントは、必須入力項目に値が入力されるまで、ダイアログを閉じることができません。このようなダイアログを閉じるには、[閉じる]ボタンに formnovalidate 属性を使用するか、[閉じる]ボタンがクリックされたときにダイアログオブジェクトの close() メソッドを呼び出すかしてください。

html
<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

js
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() を使用しても同様にダイアログを閉じることができます。

様々な closedby 動作の比較

この例は、closedby属性の様々な値による動作の違いを示しています。

HTML

3 つの <button> 要素と 3 つの <dialog> 要素があります。各ボタンは、closedby 属性の 3 つの値(nonecloserequestany)のいずれかの動作を示す異なるダイアログを開くようにプログラムされています。各 <dialog> 要素には、それを閉じるために使用される <button> 要素が含まれていることに注意してください。

html
<p>表示する <code>&lt;dialog&gt;</code> の種類を選択:</p>
<div id="controls">
  <button id="none-btn"><code>closedby="none"</code></button>
  <button id="closerequest-btn">
    <code>closedby="closerequest"</code>
  </button>
  <button id="any-btn"><code>closedby="any"</code></button>
</div>

<dialog closedby="none">
  <h2><code>closedby="none"</code></h2>
  <p>
    提供された特定の機構を操作することによってのみ閉じることが可能です。
    この場合は、下部の[閉じる]ボタンを押してください。
  </p>
  <button class="close">閉じる</button>
</dialog>

<dialog closedby="closerequest">
  <h2><code>closedby="closerequest"</code></h2>
  <p>[閉じる]ボタンまたは Esc キーで閉じられます。</p>
  <button class="close">閉じる</button>
</dialog>

<dialog closedby="any">
  <h2><code>closedby="any"</code></h2>
  <p>
    [閉じる]ボタン、Esc キー、またはダイアログの外側をクリックすることで閉じられます。「簡単な解除」の動作です。
  </p>
  <button class="close">閉じる</button>
</dialog>

JavaScript

ここでは、メインコントロールの <button> 要素、<dialog> 要素、ダイアログ内の「閉じる」の <button> 要素を参照するために、異なる変数を割り当てます。まず click イベントリスナーを addEventListener で各コントロールボタンに割り当て、そのイベントハンドラー関数で関連する <dialog> 要素を showModal() で開くようにします。 次に「閉じる」の <button> 要素をループ処理し、それぞれに click イベントハンドラー関数を割り当てます。この関数は対応する <dialog> 要素を、 close() で閉じます。

js
const noneBtn = document.getElementById("none-btn");
const closerequestBtn = document.getElementById("closerequest-btn");
const anyBtn = document.getElementById("any-btn");

const noneDialog = document.querySelector("[closedby='none']");
const closerequestDialog = document.querySelector("[closedby='closerequest']");
const anyDialog = document.querySelector("[closedby='any']");

const closeBtns = document.querySelectorAll(".close");

noneBtn.addEventListener("click", () => {
  noneDialog.showModal();
});

closerequestBtn.addEventListener("click", () => {
  closerequestDialog.showModal();
});

anyBtn.addEventListener("click", () => {
  anyDialog.showModal();
});

closeBtns.forEach((btn) => {
  btn.addEventListener("click", () => {
    btn.parentElement.close();
  });
});

結果

レンダリング結果は次のとおりです。

各ボタンをクリックしてダイアログを開いてみてください。最初のダイアログは[閉じる]ボタンをクリックすることでのみ閉じられます。2 つ目のダイアログは、Esc キーを押すなど、端末固有のユーザー操作でも閉じられます。3つ目のダイアログは完全な「簡単な解除」動作を備えているため、ダイアログの外側をクリックまたはタップしても閉じられます。

アニメーションするダイアログ

<dialog> 要素は、非表示時には display: none; 表示時には display: block; と設定され、最上位レイヤーおよびアクセシビリティツリーから削除されたり、追加されたりします。したがって、 <dialog> 要素をアニメーションさせるには、 display プロパティをアニメーション化する必要があります。対応ブラウザーでは、display プロパティを離散的なアニメーション型で変化させてアニメーション化します。具体的には、ブラウザーは none と他の display 値を交互に切り替えることで、アニメーション化されたコンテンツがアニメーションの全期間にわたって表示されるようにします。

例えば、

  • displaynone から block(あるいは他の可視の display 値)にアニメーションする場合、アニメーション再生時間の 0% で値が block に切り替わり、常に表示されます。
  • displayblock(または他の可視の 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-discretedisplayoverlay トランジション(または transition 一括指定)に設定すると、既定ではアニメーションできないこれら2つのプロパティで離散トランジションが有効になります。

この機能がどのようなものか見ていくために、例えば次のような例を挙げてみましょう。

HTML

この HTML は <dialog> 要素と、ダイアログを表示させるためのボタンを格納しています。さらに、<dialog> 要素には、それ自体を閉じさせるためのボタンがもう一つ格納されています。

html
<dialog id="dialog">
  ここがコンテンツ
  <button class="close">閉じる</button>
</dialog>

<button class="show">モーダル表示</button>
CSS

この CSS では、@starting-style ブロックを記述して、opacity および transform プロパティのトランジション開始時のスタイル、dialog:open 状態のトランジション終了時のスタイル、<dialog> が表示された後に元の状態に戻る際の既定の dialog 状態のスタイルを定義します。注意してほしいのは、 <dialog>transition リストには、これらのプロパティだけでなく、displayoverlay プロパティも含まれ、それぞれに allow-discrete が設定されていることです。

また、開いたときに現れる <dialog> の背後に現れる ::backdropbackground-color プロパティに開始時のスタイル値を設定し、素敵な暗転アニメーションを指定しました。 dialog:open::backdrop セレクターは、ダイアログが開いているときに、<dialog> 要素の背景のみを選択します。

css
/* 開いた状態のダイアログ */
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: transparent;
  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: transparent;
  }
}

メモ: :open 擬似クラスに非対応のブラウザーでは、属性セレクター dialog[open] が使用して <dialog> 要素が開いた状態のときにスタイルを適用することができます。

JavaScript

JavaScript で、表示ボタンと閉じるボタンにイベントハンドラーを追加し、クリックされたときに <dialog> を表示させたり閉じたりするイベントを発生させます。

js
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> 要素には、それ自体を閉じるためのボタンが格納されています。

html
<dialog id="dialog">
  ここがコンテンツです
  <button class="close">閉じる</button>
</dialog>

<button class="show">モーダル表示</button>
CSS

CSSでは、<dialog>を閉じられた状態と表示させた状態の間でアニメーションさせるためのキーフレームを定義し、さらに、<dialog>の背景のフェードインアニメーションも定義しています。ダイアログボックスのアニメーションには、実際のアニメーション効果が再生時間全体にわたって確実に表示されるようにするための display のアニメーションが含まれます。 バックグラウンドのフェードアウトのアニメーションは不可能であることに注意してください。背景は、ダイアログボックスが閉じられるとすぐに DOM から除去されるため、アニメーション化する何かがあるわけではありません。

css
dialog {
  animation: fade-out 0.7s ease-out;
}

dialog:open {
  animation: fade-in 0.7s ease-out;
}

dialog:open::backdrop {
  background-color: black;
  animation: backdrop-fade-in 0.7s ease-out forwards;
}

/* アニメーションのキーフレーム */

@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% {
    opacity: 0;
  }

  100% {
    opacity: 0.25;
  }
}

body,
button {
  font-family: system-ui;
}
JavaScript

最後に、JavaScript でボタンにイベントハンドラーを追加し、<dialog> を表示させたり閉じたりできるようにします。

js
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
# the-dialog-element

ブラウザーの互換性

関連情報

  • HTMLDialogElement インターフェイス
  • close イベント(HTMLDialogElement インターフェイス)
  • cancel イベント(HTMLDialogElement インターフェイス)
  • open プロパティ(HTMLDialogElement インターフェイス)
  • inert グローバル属性(HTML 要素)
  • CSS の ::backdrop 擬似要素
  • ウェブフォーム(学習領域)