<button type="button" class="dialog__open-button" aria-expanded="false" aria-controls="modal">
  モーダルダイアログを開く
</button>

<dialog id="modal" class="dialog">
  <div class="dialog__inner">
    <h2 class="dialog__heading">モーダルダイアログ</h2>
    <button type="button" aria-controls="modal" aria-expanded="false" class="dialog__close-button">
      モーダルダイアログを閉じる
    </button>
  </div>
</dialog>
.dialog {
padding:initial;
}
const dialog: HTMLDialogElement | null = document.querySelector('.dialog');
const openDialogButton: HTMLButtonElement | null = document.querySelector('.dialog__open-button');
const closeDialogButton: HTMLButtonElement | null = document.querySelector('.dialog__close-button');

const scrollLock = () => {
  const scrollY = window.scrollY;
  document.body.style.position = 'fixed';
  document.body.style.top = `-${scrollY}px`;
  document.body.style.left = '0';
  document.body.style.width = '100%';
  document.body.style.overflowY = 'scroll';
};

const scrollUnlock = () => {
  const scrollY = document.body.style.top;
  document.body.style.position = '';
  document.body.style.top = '';
  document.body.style.left = '';
  document.body.style.width = '';
  document.body.style.overflowY = '';
  window.scrollTo(0, parseInt(scrollY || '0', 10) * -1);
};

const openDialog = () => {
  dialog.showModal();
  openDialogButton.setAttribute('aria-expanded', 'true');
  closeDialogButton?.setAttribute('aria-expanded', 'true');
  scrollLock();
};

const closeDialog = () => {
  openDialogButton.setAttribute('aria-expanded', 'false');
  closeDialogButton.setAttribute('aria-expanded', 'false');
  if (dialog.open) {
    dialog.close();
  }
  scrollUnlock();
};

openDialogButton.addEventListener('click', () => {
  openDialog();
});

closeDialogButton.addEventListener('click', () => {
  closeDialog();
});

dialog.addEventListener('click', (event) => {
    // dialogのpadding部分ではなく、dialogの直接の子要素がクリックされた場合のみイベントリスナーを起動
    if (!event.target.closest('.dialog__inner')) {
        closeDialog();
    }
});
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.