web

軽量でアクセシビリティに配慮されたMicromodal.jsを使う

公開日:2022年1月21日
最終更新日:2022年1月30日
目次
  • サンプル
  • インストール
  • HTML
  • CSS
  • JavaScript
  • オプション

Micromodal.jsはWAI-ARIA guidelinesに準拠した実装をしていて、しかも1.9kbしかありません。
https://micromodal.vercel.app/

ただ開いて閉じるだけのモーダルを作るのは難しくないですが、Micromodal.jsを使うとアクセシビリティの課題もクリアできます。具体的には以下の対応などをしています。

  • モーダルを開いてる間は裏側のコンテンツを操作しない、フォーカスを当てない
  • モーダルを開いてる間はモーダル内にのみフォーカスが当たるようにする
  • escキーで閉じる


サンプル

CSSは自分で書く必要がありますが、逆にいうと余計なスタイリングがないので、カスタマイズしやすいです。


インストール

以下でライブラリを追加します

yarn add micromodal


HTML

最低限ですが、以下のような構造です。

  • モーダルにid名を指定しておく
  • data-micromodal-trigger でid名を指定すると、そのモーダルのトリガーに
  • data-micromodal-close を指定するとそのタグでモーダルを閉じる
// 開くボタン
<button data-micromodal-trigger="modal">Modal</button>

// モーダル
<div class="modal micromodal-slide" id="modal" aria-hidden="true">
  <div class="modal__overlay" tabindex="-1" data-micromodal-close="modal">
    <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-title">
      // モーダル コンテンツ
      <button aria-label="Close modal" data-micromodal-close="modal">Close</button>
    </div>
  </div>
</div>


CSS

CSSは以下です。ふわっと表示して、消えるアニメーションのコードも書いてます。

.modal {
  display: none;

  &.is-open {
    display: block;
  }

  &[aria-hidden="false"] {
    .modal__overlay {
      animation: mmfadeIn 0.3s cubic-bezier(0, 0, 0.2, 1);
    }

    .modal__container {
      animation: mmslideIn 0.3s cubic-bezier(0, 0, 0.2, 1);
    }
  }

  &[aria-hidden="true"] {
    .modal__overlay {
      animation: mmfadeOut 0.3s cubic-bezier(0, 0, 0.2, 1);
    }

    .modal__container {
      animation: mmslideOut 0.3s cubic-bezier(0, 0, 0.2, 1);
    }
  }

  &__container,
  &__overlay {
    will-change: transform;
  }

  &__overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.2);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 100;
  }

  &__container {
    width: 94%;
    max-width: 820px;
    background: #fff;
    padding: 24px;
  }
}

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

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

@keyframes mmslideIn {
  from {
    transform: translateY(15%);
  }
  to {
    transform: translateY(0);
  }
}

@keyframes mmslideOut {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(-10%);
  }
}


JavaScript

JSは以下です。オプションがいくつか用意されています。

import MicroModal from 'micromodal'

MicroModal.init({
  onShow: modal => console.info(`${modal.id} is shown`),
  onClose: modal => console.info(`${modal.id} is hidden`),
  openTrigger: 'data-custom-open',
  closeTrigger: 'data-custom-close',
  openClass: 'is-open',
  disableScroll: true,
  disableFocus: false,
  awaitOpenAnimation: false,
  awaitCloseAnimation: false,
  debugMode: true
});


オプション

  • onShow
    • モーダルが開いた時に実行する関数
  • onClose
    • モーダルが閉じた時に実行する関数
  • openTrigger
    • モーダルを開くデータ属性をカスタマイズできる
    • デフォルトは data-micromodal-trigger
  • closeTrigger
    • モーダルを閉じるデータ属性をカスタマイズできる
    • デフォルトは data-micromodal-close
  • openClass
    • モーダルを開いた時にモーダルにつけるclass
    • デフォルトは is-open
  • disableScroll
    • モーダルを開いてる間、ページのスクロールをしないようにする
  • disableFocus
    • モーダルを開いた時に、モーダル内のフォーカス可能な要素に自動でフォーカスしないようにする
  • awaitOpenAnimation
    • アニメーションを使ってモーダルを開くようにする
  • awaitCloseAnimation
    • アニメーションの終了を待ってから、モーダルを非表示にする
  • debugMode
    • trueにするとconsoleに表示される警告を抑制する


軽量でアクセシビリティに配慮されていて、使い方も簡単なのでおすすめです。

About the author

大阪でフロントエンドエンジニアをしています。写真を撮るのが趣味です。よかったら500pxに載せてる写真も見てください。
web上に公開しているので、正確さに可能な限り努力してますが、個人の備忘録程度に書いてるので、ご自身の判断で参考程度に読んでください。
間違いやご意見があれば、コンタクトやSNSに気軽にご連絡ください。

Read next

Category

  • web
  • 雑記