ウェブサイトでモーダルダイアログを実装する方法はいくつかありますが、ネイティブ HTML 要素である<dialog>タグを使うことで、シンプルかつ手軽に実装できます。この記事では、<dialog>タグの基本的な使い方や、カスタマイズ方法について解説します。

LINE着せかえ「回るお寿司」販売中!

<dialog> タグとは?

<dialog>タグは、HTML5 で導入された要素で、モーダルダイアログを簡単に作成できるタグです。<dialog>タグで囲われたコンテンツは、ページの読み込み時点ではデフォルトで非表示となっており、表示・非表示の切り替えには JavasScript を使用する必要があります。

<dialog> によるモーダルダイアログの実装方法

以下は、<dialog>タグを使ったモーダルダイアログの基本的な実装例です。

HTML

HTML は、<dialog>と、それを開閉するための<button>があるだけのシンプルなものです。

<dialog id="modalDialog">
  <p>これはモーダルダイアログです。</p>
  <button id="closeDialog">閉じる</button>
</dialog>
<button id="openDialog">開く</button>

JavaScript

JavaScript では、開くボタンのクリック時に<dialog>showModal()メソッド、閉じるボタンのクリック時にclose()メソッドを実行するだけです。

window.addEventListener("DOMContentLoaded", function () {
  // ダイアログ要素の取得
  const dialog = document.getElementById('modalDialog');

  // 開くボタン押下時の処理
  document.getElementById('openDialog').addEventListener('click', function() {
    dialog.showModal();
  });

  // 閉じるボタン押下時の処理
  document.getElementById('closeDialog').addEventListener('click', function() {
    dialog.close();
  });
});

たったこれだけで、モーダルダイアログが出来てしまいます。

表示サンプル

See the Pen html-modal-dialog 01 by YUTSUZO (@YUTSUZO) on CodePen.

<dialog> の見た目を CSS で整える

デフォルトのスタイルをリセットする場合

デフォルトの<dialog>には、いくつかのクセが強いスタイルが適用されています。デフォルトのスタイルをリセットして、完全に自分で制御したいという場合、以下のようなリセット用スタイルを記述しておくと、カスタマイズしやすくなります。

:where(dialog) {
  inset: auto;
  margin: 0;
  padding: 0;
  width: auto;
  height: auto;
  max-width: none;
  max-height: none;
  border: none;
  background: transparent;
  box-sizing: border-box;
  overflow: visible;
}

ただし、通常の使用であればここまでする必要はなく、デフォルトのスタイルにある程度上書きするだけで事足ります。

dialog {
  inset: 20px;
  padding: 20px;
  width: auto;
  height: auto;
  max-width: 800px;
  max-height: 600px;
  border: none;
  box-sizing: border-box;
}

背景(オーバーレイ)は ::backdrop 疑似要素で指定

ダイアログを表示中の背景(オーバーレイ)にスタイルを当てる場合は、::backdrop疑似要素を使って指定します。

dialog::backdrop {
  background: rgb(0 0 0 / 0.75);
  backdrop-filter: blur(5px);
}

モーダルダイアログにアニメーションを追加する

モーダルダイアログの開閉時にアニメーションをつける場合は、transitionの開始を示すクラスなどを追加し、アニメーションを設定します。

CSS

dialog {
  padding: 20px;
  border: none;
  box-sizing: border-box;
  transition: 0.4s;
}

dialog::backdrop {
  background: rgb(0 0 0 / 0.75);
  backdrop-filter: blur(4px);
  transition: 0.4s;
}

dialog.in-transition,
dialog.in-transition::backdrop {
  /* 開始時のスタイルを記述 */
  opacity: 0;
}

JavaScript

window.addEventListener("DOMContentLoaded", function () {
  // ダイアログ要素の取得
  const dialog = document.getElementById('modalDialog');

  // 開くボタン押下時の処理
  document.getElementById('openDialog').addEventListener('click', function () {
    // アニメーション中のクラスを付ける
    dialog.classList.add('in-transition');

    // ダイアログを開く
    dialog.showModal();

    // showModal() が終わったらクラスを削除する
    requestAnimationFrame(function () {
      dialog.classList.remove('in-transition')
    });
  });

  // 閉じるボタン押下時の処理
  document.getElementById('closeDialog').addEventListener('click', function () {
    // アニメーション中のクラスを付ける
    dialog.classList.add('in-transition');

    // transition が終わったらクラスを削除し、ダイアログを閉じる
    dialog.addEventListener('transitionend', function () {
      dialog.classList.remove('in-transition');
      dialog.close();
    },{
      once: true,
    });
  });
});

表示サンプル

See the Pen html-modal-dialog 02 by YUTSUZO (@YUTSUZO) on CodePen.

ただし、2025 年 3 月現在、Firefox では ::backdrop 疑似要素にアニメーションが効かないことに注意が必要です。

背景が押されたらダイアログを閉じるようにする

背景をクリックした時にダイアログを閉じたい場合、ダイアログ自体がクリックされたら閉じるという処理を JavaScript に追加し、ダイアログ内はinnerなどのクラスで囲います

こうすることで、ダイアログの中がクリックされた場合はinnerがクリックされたとみなされるので閉じず、背景がクリックされた場合のみダイアログが閉じられるようになります

HTML

<dialog id="modalDialog">
  <div class="inner">
    <p>これはモーダルダイアログです。</p>
    <button id="closeDialog">閉じる</button>
  </div>
</dialog>
<button id="openDialog">開く</button>

CSS

dialog {
  padding: 0;
  border: none;
  transition: 0.4s;
}

dialog .inner {
  padding: 20px;
  height: 100%;
  box-sizing: border-box;
}

dialog::backdrop {
  background: rgb(0 0 0 / 0.75);
  backdrop-filter: blur(4px);
  opacity: 1;
  transition: 0.4s;
}

dialog.in-transition,
dialog.in-transition::backdrop {
  opacity: 0;
}

JavaScript

window.addEventListener("DOMContentLoaded", function () {
  // ダイアログ要素の取得
  const dialog = document.getElementById('modalDialog');

  // 開くボタン押下時の処理
  document.getElementById('openDialog').addEventListener('click', function () {
    // アニメーション中のクラスを付ける
    dialog.classList.add('in-transition');

    // ダイアログを開く
    dialog.showModal();

    // showModal() が終わった後にクラスを削除する
    requestAnimationFrame(function () {
      dialog.classList.remove('in-transition')
    });
  });

  // 閉じるボタン押下時の処理
  document.getElementById('closeDialog').addEventListener('click', function () {
    // アニメーション中のクラスを付ける
    dialog.classList.add('in-transition');

    // transition 終了後にクラスを削除し、ダイアログを閉じる
    dialog.addEventListener('transitionend', function () {
      dialog.classList.remove('in-transition');
      dialog.close();
    },{
      once: true,
    });
  });

  dialog.addEventListener('click', function (event) {
    // ダイアログの中がクリックされた場合は、inner がクリックされたとみなされるので閉じない
    if (event.target === dialog) {
      dialog.close();
    }
  });
});

表示サンプル

See the Pen Untitled by YUTSUZO (@YUTSUZO) on CodePen.

終わりに

<dialog>タグを活用することで、シンプルかつ効率的にモーダルウィンドウを実装できます。さらに CSS を駆使すれば、より洗練されたデザインやアニメーションを追加することも可能です。この記事を参考に、ぜひ自分のプロジェクトに取り入れてみてください。

参考