はじめに

Webサイトやアプリケーションでよく使用されるUIパターンの一つに「モーダル」があります。モーダルは、ユーザーの注意を特定のコンテンツに集中させるために使用される重要なUIコンポーネントです。

今回は、HTML5で導入された<dialog>タグを使用して、シンプルかつ効果的なモーダルを実装する方法を解説します。

HTMLの構造

まず、モーダルのHTMLの構造を見てみましょう。


<dialog id="mdl-pejiVKU1" class="modal-container modal-viewDialog">
  <ul class="modal-wrapper">
    <li class="modal-slide">
      <a class="modal-ifield">
        <picture class="modal-thumbnail">
          <img src="画像のURL" alt="">
        </picture>
        <div class="modal-caption">
          <h4 class="modal-title">Image:01</h4>
        </div>
      </a>
    </li>
  </ul>
  <a class="modal-closer js-clsrVKUA" aria-label="閉じる">×</a>
</dialog>

ポイント:

  • <dialog>タグを使用することで、ブラウザネイティブのモーダル機能を利用できます。
  • 各モーダルに一意のIDを付与します(例:id="mdl-pejiVKU1")。
  • モーダルを閉じるボタンには特定のクラス(js-clsrVKUA)を付与し、JavaScriptから操作できるようにします。

JavaScriptの実装

次に、モーダルを制御するJavaScriptのコードを見ていきます。


(function () {
  const mdalOpnrs = Array.from(document.querySelectorAll(".js-opnrVKUA"));
  const mdalClsrs = Array.from(document.querySelectorAll(".js-clsrVKUA"));
  const { body } = document;

  function openModal(modalId) {
    const modal = document.getElementById(modalId);
    if (modal) {
      modal.showModal();
      modal.classList.add('is-opened');
      body.classList.add('is-modaled');
    }
  }

  function closeModal(modal) {
    modal.close();
    modal.classList.remove('is-opened');
    body.classList.remove('is-modaled');
    mdalOpnrs.forEach(mdalOpnr => mdalOpnr.classList.remove('is-pressed'));
  }

  mdalOpnrs.forEach(mdalOpnr => {
    mdalOpnr.addEventListener('click', function (e) {
      e.preventDefault();
      const modalId = this.getAttribute('data-opento');
      openModal(modalId);
      this.classList.add('is-pressed');
    });
  });

  mdalClsrs.forEach(mdalClsr => {
    mdalClsr.addEventListener('click', function (e) {
      e.preventDefault();
      const modal = this.closest('dialog');
      closeModal(modal);
    });
  });

  document.querySelectorAll('dialog').forEach(modal => {
    modal.addEventListener('cancel', function () {
      closeModal(this);
    });
  });
})();

主な機能:

  1. モーダルを開く
  • openModal関数は、指定されたIDのモーダルを表示します。
  • showModal()メソッドを使用して、dialogを表示します。
  • モーダルとbody要素にクラスを追加して、スタイリングに利用します。
  1. モーダルを閉じる
  • closeModal関数は、モーダルを閉じ、関連するクラスを削除します。
  • close()メソッドを使用して、dialogを閉じます。
  1. イベントリスナーの設定
  • モーダルを開くボタン(.js-opnrVKUA)にクリックイベントを設定します。
  • モーダルを閉じるボタン(.js-clsrVKUA)にクリックイベントを設定します。
  • cancelイベントをリッスンして、Escキーでのモーダル閉鎖に対応します。

実装のポイント

  1. アクセシビリティ
  • <dialog>タグを使用することで、スクリーンリーダーとの互換性が向上します。
  • 閉じるボタンにはaria-label属性を使用して、その目的を明確にしています。
  1. 柔軟性
  • data-opento属性を使用して、開くべきモーダルのIDを指定します。これにより、複数のモーダルを簡単に管理できます。
  1. パフォーマンス
  • イベントデリゲーションを使用せず、必要な要素にのみイベントリスナーを追加しています。これにより、不要なイベント処理を減らしています。
  1. スタイリングの容易さ
  • モーダルの状態に応じてクラスを追加/削除することで、CSSでの柔軟なスタイリングが可能になります。

まとめ

<dialog>タグを使用したモーダルの実装は、シンプルでありながら強力です。ブラウザネイティブの機能を活用することで、アクセシビリティと性能の両面で優れたUIを提供できます。

この実装をベースに、プロジェクトの要件に応じてカスタマイズすることで、様々なニーズに対応できるでしょう。