Webページでモーダルウィンドウやダイアログ表示を実装する際はJavaScriptのライブラリやプラグイン等を使って組み込むことが多いですが、HTMLのdialogタグを使うととても簡単に実装することができます。

dialogタグを使用することで、ダイアログを表示させたり非表示にしたりするJavaScript動作をブラウザが処理してくれることになるので、アクセシビリティにもよいと言われています。(dialogタグでも表示するための指示はJavaScriptを使用しますが)

IEのサポートも終わり、主要ブラウザでdialog要素がサポートされたことで活用できる機会が増えてきたので実装する方法をいくつかのパターンで紹介してみます。

dialogタグを使ってダイアログ表示

まずは基本的な使用方法として、dialogタグを使った場合のHTMLから。

ダイアログで表示する内容をdialogタグの中に記載し、併せてダイアログを表示するためのボタンと閉じるためのボタンを設置します。

ボタンにはidまたはクラスをつけておきます。

<dialog>
  <p>これはHTMLのdialogタグで作られたダイアログです。</p>
  <button id="dialog-close">ダイアログを閉じる</button>
</dialog>

<button id="dialog-open">ダイアログを開く</button>

dialogタグで書かれた内容はデフォルトではWebページ上に表示されません。

表示するには、JavaScriptで表示と非表示を実行する処理を指定します。

dialogタグを表示するには「showModal()」メソッドを使用し、閉じるには「close()」メソッドを使用します。

この「showModal()」と「close()」メソッドを使えばJavaScriptで細かな処理を追加せずにブラウザ側でダイアログの表示と非表示の動作を実行してくれます。

const dialog = document.querySelector('dialog');

// ダイアログを開く
document.getElementById('dialog-open').addEventListener('click', function() { 
  dialog.showModal();
});

// ダイアログを閉じる
document.getElementById('dialog-close').addEventListener('click', function() {
  dialog.close();
});

ダイアログをCSSなどで装飾せずにとりあえず「showModal()」「close()」メソッドで表示と非表示を切り替える動作は以下です。

See the Pen
HTML dialog [1]
by BLACKFLAG (@BlackFlag)
on CodePen.

参考までに、dialogタグにopen属性を付けることで、ページロード時にデフォルトでダイアログを表示させておくことができます。
※open属性で表示した場合はオーバーレイが表示されなかったり「showModal()」メソッドで表示する場合と違いがあります。

See the Pen
HTML dialog [2]
by BLACKFLAG (@BlackFlag)
on CodePen.

dialogにCSSで装飾を加え、アニメーション表示とオーバーレイクリックで閉じるようにする

JavaScriptでモーダルウィンドウやダイアログを実装する時と同様に、dialogタグでも簡単にダイアログ要素にCSSで装飾することができます。

ダイアログ自体の装飾は単純にdialogタグに対してサイズや余白などをCSSで指定します。

ダイアログを表示する際の背景にあたるオーバーレイ部分はdialogタグの疑似要素「::backdrop」で色味や透過度を指定することができます。

dialog {
  background: #fff;
  border: #333 1px solid;
  border-radius: 10px;
  box-shadow: 0 0 10px #666;
  color: #333;
  width: 80%;
  &::backdrop {
    background: rgba(0, 0, 0, 0.5);
  }
}

CSSでの装飾と合わせて、ダイアログ表示時にアニメーションを付ける動作サンプルは以下です。

表示のアニメーションはJavaScript側でダイアログを表示する際に「showModal()」メソッドと併せてCSSクラスの「.show」を付与することでアニメーション制御させてます。

See the Pen
HTML dialog [3]
by BLACKFLAG (@BlackFlag)
on CodePen.

モーダルウィンドウを使う場合はオーバーレイ部分をクリックさせてウィンドウを閉じるようにしたいですが、dialogタグの疑似要素「::backdrop」にはクリックイベントなどの指定ができません。

実現するにはいくつか方法がありますが、上記のサンプルではJavaScript側でクリックされた位置がダイアログ本体の中(「.dialog-inner」の中)かどうかを判別して、そうでなかった場合はダイアログ枠外という判断になり、「close()」メソッドの閉じる動作を実行させる制御をしています。

dialogをページ内に複数設置

dialogタグを使ったダイアログ表示をページ内に複数設置する場合は、dialogタグに固有のidを付与して、表示用ボタンにdata属性でdialogタグのidと紐づけをして実装します。

<dialog id="dialog-1">
  <div class="dialog-inner">
    <p>これはダイアログ1です。</p>
    <button class="dialog-close">ダイアログ1を閉じる</button>
  </div>
</dialog>

<dialog id="dialog-2">
  <div class="dialog-inner">
    <p>これはダイアログ2です。</p>
    <button class="dialog-close">ダイアログ2を閉じる</button>
  </div>
</dialog>

<button class="dialog-open" data-dialog="dialog-1">ダイアログ1を開く</button>
<button class="dialog-open" data-dialog="dialog-2">ダイアログ2を開く</button>
const dialogs = document.querySelectorAll('dialog');

// ダイアログを開く
const open = document.querySelectorAll('.dialog-open');
open.forEach(button => {
  button.addEventListener('click', () => {
    const dialogId = button.getAttribute('data-dialog');
    const dialog = document.getElementById(dialogId);
    dialog.showModal();
    dialog.classList.add('show');
  });
});

// ダイアログを閉じる
const close = document.querySelectorAll('.dialog-close');
close.forEach(button => {
  button.addEventListener('click', () => {
  const dialog = button.closest('dialog');
  dialog.classList.remove('show');
  setTimeout(() => dialog.close(), 500);
  });
});

// オーバーレイクリックでダイアログを閉じる
dialogs.forEach(button => {
  button.addEventListener('click', (event) => {
    if(event.target.closest('.dialog-inner') === null) {
      const dialog = button.closest('dialog');
      dialog.classList.remove('show');
      setTimeout(() => dialog.close(), 500);
    }
  });
});

これを実行させたパターンは以下です。

See the Pen
HTML dialog [4]
by BLACKFLAG (@BlackFlag)
on CodePen.

dialogタグの対象ブラウザについては以下です。

以上が、dialogタグを使ったダイアログ、モーダルウィンドウ実装の紹介でした。

JavaScriptライブラリで実装するよりもdialogタグを使うことでとてもシンプルな構成でモーダルウィンドウなどのダイアログUIの組み込みが可能で、ユーザービリティやアクセシビリティにも配慮した構成で実装できるのでメリットも多いです。

モーダルウィンドウやダイアログをdialogタグを使って実装する際にぜひ。。。