HTML / Element

dialog要素の使い方

HTMLのdialog要素は、確認、入力、設定などのために一時的に表示する小さなウィンドウを表します。ブラウザーが、表示・フォーカス・閉じる操作の基本を扱える標準の部品です。

先に結論

現在のページの上に確認や入力の画面を重ねるなら、dialogを使います。モーダルとして表示する場合はshowModal()を呼び出します。

開くための操作にはbuttonを使い、ダイアログ内には必ず閉じる方法を用意します。追加情報を開閉するだけなら、detailsのほうが適切です。

最小例

<button type="button" id="open-dialog">確認画面を開く</button>

<dialog id="confirm-dialog" aria-labelledby="confirm-title">
  <h2 id="confirm-title">送信しますか?</h2>
  <p>内容を確認してから送信してください。</p>
  <form method="dialog">
    <button type="submit" value="cancel" autofocus>キャンセル</button>
    <button type="submit" value="ok">送信する</button>
  </form>
</dialog>

<script>
  const openDialog = document.querySelector('#open-dialog');
  const confirmDialog = document.querySelector('#confirm-dialog');
  openDialog.addEventListener('click', () => confirmDialog.showModal());
</script>

この例では、showModal()でモーダルダイアログを開き、method="dialog"のフォーム内のボタンで閉じます。実際の送信処理が必要な場合は、ダイアログを閉じた後にreturnValueを確認して処理します。

サンプルの確認画面

これはページ内の実例です。確認ボタンを押すと、ダイアログが閉じます。

モーダルと通常のダイアログ

方法画面の状態主な用途
showModal()モーダル。ダイアログの外側を操作しない確認、削除、入力の完了待ち
show()通常のダイアログ。ページの他の部分も操作できる補助的な情報や、並べて使う小さな操作画面
open属性表示状態を表す。モーダルかどうかだけでは決まらない状態の確認。開閉にはメソッドを使う

確認を終えるまで背景の操作を止めたい場合はshowModal()を使います。単にopen属性を付け外しするだけでは、閉じるイベントやモーダル状態の後処理まで正しく行えないことがあります。

タイトルとフォーカスを用意する

ダイアログには、何のための画面か分かる見出しを置き、aria-labelledbyでその見出しと関連付けます。開いた直後に操作してほしい入力欄やボタンには、必要に応じてautofocusを付けます。

モーダルを閉じた後に、利用者が開く操作を続けられるよう、ブラウザーは元のフォーカスへ戻ろうとします。フォーカスを画面の外へ逃がさないこと、キーボードだけでも閉じられることを確認しましょう。

フォームで選択結果を受け取る

form method="dialog"は通常のネットワーク送信を行わず、フォームの送信ボタンでダイアログを閉じるために使えます。送信ボタンのvalueは、閉じた後のdialog.returnValueで確認できます。

dialog.addEventListener('close', () => {
  if (dialog.returnValue === 'ok') {
    // 確認されたときの処理
  }
});

よくある間違い

  • divをダイアログのように動かし、フォーカスやEscapeキーの処理を自作する。
  • ダイアログを開いたままにする閉じるボタンを用意しない。
  • show()を使っているのに、背景を操作できないモーダルだと思い込む。
  • 見出しや説明がなく、利用者が何を確認しているか分からない。
  • 重要な説明や必須の操作を、閉じたダイアログの中だけに置く。

Atlasで詳しく確認する

open状態、モーダル時のtop layerと背景のinert化、フォーカス、cancelcloserequestClose()closedby、フォームとの境界、ブラウザー実装とアクセシビリティの確認範囲は、Yugien Atlasのdialog要素ページで詳しく整理しています。