超簡単にモーダル(ダイアログ)が作れるdialogタグの使い方

dialogタグとは

dialogタグはモーダル(ダイアログ)を超簡単に実装するための要素です。

dialogタグという名前ですが、日本ではこのようなUIはモーダルと呼称することが多いので、この記事ではHTMLのdialogタグ以外の部分はモーダル(modal)と書いています。

モーダルを作るにはHTML, CSS, JavaScriptのコードをたくさん書く必要がありますが、dialogタグを使用すれば必要最小限のコードでモーダルを作成できます。

dialogタグはほとんどのブラウザで使用可能です。

Dialog element | Can I use...

dialogタグの使い方

まず、モーダルを開くためのボタン、モーダル(dialogタグ)などを以下のようにHTML内に配置します。

HTML
<button id="openModal">モーダルを開く</button>
<dialog id="modal">
    <p>これはモーダルです。</p>
    <button id="closeModal">閉じる</button>
</dialog>

次にJavaScriptでモーダルを開く処理と、閉じる処理を以下のように記述します。

dialogタグを使用している場合は、showModal()で開く、close()で閉じる処理が実行できます。

JavaScript
const modal = document.getElementById('modal')
const openButton = document.getElementById('openModal')
const closeButton = document.getElementById('closeModal')

// モーダルを開く
openButton.addEventListener('click', () => {
    modal.showModal()
})

// モーダルを閉じる
closeButton.addEventListener('click', () => {
    modal.close()
})

これだけでモーダルの作成は完了です。

記事のタイトル通り、超簡単に実装できます。

超簡単にモーダル(ダイアログ)が作れるdialogタグの使い方

dialogタグで作成したモーダルのサンプル

dialogタグの幅について

モーダルの幅はwidthが指定されていなければ、テキスト量が多いと画面幅の最大まで広がります。

最大まで広がるとUIがモーダルっぽくなくなるので、テキスト量が多い場合はwidthやmax-widthを指定してください。

dialogタグだとescキーで閉じる

dialogタグを使用したモーダルだと、escキーを押すと閉じることができます。

表示直後であればbuttonがフォーカスされているのでEnterキーでも閉じられます。

Safariだとモーダル表示時に閉じるボタンに青い枠線が付くので、枠線を付けたくなければボタンにoutline: noneを追記してください。

モーダルの背景を暗くする(色を変更)

モーダルのサンプルを見た際に、背景の透過色をもう少し暗くしたいと思った方もいるでしょう。

モーダルの背景の色はCSSで ::backdrop にbackgroundを適用することで変更できます。

CSS
::backdrop {
  background: rgba(0, 0, 0, 0.8);
}
dialogタグで作成したモーダルのサンプル(::backdrop)

dialogタグで作成したモーダルのサンプル(::backdrop)

dialogタグを使用しない場合は<div class="modal-overlay">のような背景の要素とCSSを書かないといけないので、dialogタグを使うことでコード量がかなり減っていることがわかります。

モーダル表示中はスクロール不可にする

モーダルのサンプルを見ると下方向にスクロールできる状態になっています。

モーダルの表示中はスクロールさせないほうが良いので、JavaScriptでモーダル表示中はbodyタグにoverflow: hiddenを追加して、スクロールされないようにしたほうが良いです。

JavaScript
// モーダルを開く
openButton.addEventListener('click', () => {
  modal.showModal()
  document.body.style.overflow = 'hidden'
})

// モーダルを閉じる
closeButton.addEventListener('click', () => {
  modal.close()
  document.body.style.overflow = ''
})

dialogタグで作成したモーダルのサンプル(スクロール不可)

モーダルの閉じるボタンを右上に配置

モーダルの閉じるボタンを右上に配置したい場合は、CSSのpositionプロパティで位置を変更できます。

CSS
#modal {
  position: relative;
}

#closeModal {
  position: absolute;
  top: 0;
  right: 0;
  width: 30px;
  height: 30px;
  background: #FFF;
  border: none;
  font-size: 20px;
  font-weight: bold;
  cursor: pointer;
}

dialogタグにはデフォルトでoverflow: hiddenが適用されているので、閉じるボタンをdialogタグより外側に配置する場合は、overflow: visibleに変更してください。

モーダルの閉じるボタンを右上に配置

dialogタグで作成したモーダルのサンプル(閉じるボタン位置変更)

モーダルの背景をクリックして閉じる

モーダルを閉じるボタンだけでなく、背景(::backdrop)部分をクリックして閉じたいときは、getBoundingClientRect()でモーダルの範囲を取得して、範囲外がクリックされた際にclose()が実行されるようにします。

JavaScript
modal.addEventListener('click', (event) => {
  const rect = modal.getBoundingClientRect()
  if (
    event.clientX < rect.left ||
    event.clientX > rect.right ||
    event.clientY < rect.top ||
    event.clientY > rect.bottom
  ) {
    modal.close()
    document.body.style.overflow = ''
  }
})

dialogタグで作成したモーダルのサンプル(外側クリックで閉じる)

dialogタグの内側にdivタグを入れて、event.target.closest('#modalInner') === null で外側クリックの方法を解説しているサイトがありますが、この方法だとモーダルの余白部分をクリックしても閉じてしまうので、このやり方は避けたほうが良いです。

HTML
<dialog id="modal">
  <div id="modalInner">
    <p>これはモーダルです。</p>
    <p>モーダルの外側をクリックしても閉じることができます。</p>
    <button id="closeModal">×</button>
  </div>
</dialog>
JavaScript
// モーダルの外側クリックで閉じる
// これだと余白部分をクリックしても閉じてしまう!
modal.addEventListener('click', (event) => {
  if (event.target.closest('#modalInner') === null) {
    modal.close()
    document.body.style.overflow = ''
  }
})

dialogタグで作成したモーダルのサンプル2(外側クリックで閉じる)

モーダルをフェードインで表示する

モーダルにフェードインアニメーションを追加したい場合は、CSSでanimationプロパティを追加します。

CSS
::backdrop {
  background: rgba(0, 0, 0, 0.8);
  animation: fadeInBackdrop 0.3s ease;
}

#modal {
  overflow: visible;
  position: relative;
  animation: fadeInModal 0.3s ease;
}

/* 中略 */

@keyframes fadeInModal {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadeInBackdrop {
  from {
    background: rgba(0, 0, 0, 0);
  }
  to {
    background: rgba(0, 0, 0, 0.8);
  }
}

dialogタグで作成したモーダルのサンプル(フェードイン)

dialogタグのモーダルは最前面に表示される

dialogタグのモーダルはCSSのz-indexを指定しなくても最前面に表示されます。

モーダルを作成した際にモーダルよりも最前面に他の要素が表示されてしまったという問題を経験された方が多いと思いますが、dialogタグならそのような問題は発生しません。

他の要素のz-indexの数値が何であろうと、常に最前面に表示されるので、もしも今後モーダルを自身で作成する機会がありましたら、dialogタグで作成することをオススメします。