Micromodal.jsを使って、アクセシビリティに配慮したモーダルを作る

Blog

エヴァンゲリオンと同じ1995年10月生まれの中田です。
早いもので今回で3回目のブログになります。

前回までのブログではthree.jsやシェーダー等、WebGLのことばかり書いていた私ですが、もう少しマニアックではないといいますか、多くの方に読んでいただけるようなブログを書こう!と思い、今回はMicromodal.jsを使ったモーダルの作り方についてまとめることにしました。

Micromodal.jsとは

Micromodal.jsは、a11y(Webアクセビリティ)に対応したモーダルライブラリです。
このa11yは、W3C(World Wide Web Consortium)という非営利団体が行っているWAI(Web Accessibility Initiative)という取り組みの中で、日々標準化と議論がされています。
Micromodal.jsはa11yに対応しているということで、W3Cによって定められているWAI-ARIA(Web Accessibility Initiative – Accessible Rich Internet Applications)という仕様の中にあるモーダル(ダイアログ)のガイドラインに準拠しています。ガイドラインには以下のような項目があります。

  • モーダルが開いている間は後ろのコンテンツを操作することはできない。
  • モーダルが開いている間はモーダル内のコンテンツのみにフォーカスがあたるするようにする。
  • モーダルが開いたら、フォーカスをモーダル内の最初のフォーカス可能な要素に移動する。
  • escキーでモーダルを閉じる。

アクセシビリティの観点以外にも、Micromodal.jsには以下のような特徴があります。

  • 素のJavaScriptで記述されており、jQueryに依存していない。
  • 1.9KBと軽量。
  • デフォルトのスタイルがないため、自由度が高い。

今まではモーダルを実装するとなると、モーダルを自作したり、Remodalのような他のモーダル系ライブラリを使ったり…ということが多かった私ですが、このMicromodal.jsを知ってからはこれ一本で実装しています。(もちろん実務でもバリバリ使っています…!)

インストール

まず最初にインストール方法です。
npmかyarnの場合はコマンドラインで以下のコマンドを入力してください。

npm

npm install micromodal --save

yarn

yarn add micromodal --save

CDN

CDNの場合は<head>の中や<body>の閉じタグの前に以下を記述してください。

<script src="https://cdn.jsdelivr.net/npm/micromodal/dist/micromodal.min.js"></script>
<!-- または -->
<script src="https://unpkg.com/micromodal/dist/micromodal.min.js"></script>

Vue.js(Nuxt.js)

Vue.jsの場合は、インストールした後でpluginsフォルダ内にmicromodal.jsのようなファイルを作成し、以下のように記述してください。
※この記述がないと、ConsoleでMicroModal is not definedというエラーが出ます。

import Vue from 'vue'
import * as MicroModal from 'micromodal'

Vue.use(MicroModal)

使い方

HTML

次にHTMLです。以下が基本の構造ですが人によって中身のコンテンツが変わってくると思うので適宜変更して使ってください。ただ、HTMLとCSSについてはこちらにサンプルのソースコードがあるので、これをベースにしつつ各自で調整しながら使うのが良いと思います。

<div id="modal-1" aria-hidden="true">

  <div tabindex="-1" data-micromodal-close>

    <div role="dialog" aria-modal="true" aria-labelledby="modal-1-title" >

      <header>
        <h2 id="modal-1-title">
          Modal Title
        </h2>

        <button type="button" aria-label="Close modal" data-micromodal-close></button>
      </header>

      <div id="modal-1-content">
        Modal Content
      </div>

    </div>
  </div>
</div>

モーダルを開くボタン(トリガー)については以下のようになります。

<button type="button" data-micromodal-trigger="modal-1">Open</button>

JavaScript

最後にJavaScriptです。以下の一行を書くだけでOKです。非常に簡単ですね!

MicroModal.init();

オプション

もちろんオプションも用意されています。
動作させるだけなら上の一行だけで問題ないですが、カスタマイズしたい方はお好みでどうぞ!
ただ、ガイドラインの項目にもあったように、モーダルが開いている間は後ろのコンテンツは操作できないようにするべきなので、disableScroll: trueは必須オプションになるかと思います。

  • onShow
    モーダルが開いた時に実行される関数を宣言できます。
  • onClose
    モーダルが閉じた時に実行される関数を宣言できます。
  • openTrgger
    モーダルを開くトリガーにつけるカスタムデータ属性の名前を指定できます。
    デフォルト:data-micromodal-trigger
  • closeTrigger
    モーダルを閉じるトリガーにつけるカスタムデータ属性の名前を指定できます。
    デフォルト:data-micromodal-close
  • openClass
    モーダルが開いた時にモーダルに追加するクラスの名前を指定できます。
    デフォルト:is-open
  • disableScroll
    モーダルが開いている間、ページのスクロールが無効になります。
    デフォルト:false
  • disableFocus
    モーダル内の最初のフォーカス可能な要素へのオートフォーカスを無効にします。
    デフォルト:false
  • awaitOpenAnimation
    CSSアニメーションを使ってモーダルを開くか開かないかを指定できます。
    デフォルト:false
  • awaitCloseAnimation
    CSSアニメーションを使ってモーダルを閉じるか閉じないかを指定できます。
    デフォルト:false
  • debugMode
    コンソールに表示される警告を抑制できます。
    デフォルト:false

Vue.js(Nuxt.js)

先程と同様、Vue.jsで使う場合は書き方が少し異なります。
以下のようにmethods内に初期化のためのメソッド(今回でいうとinit())を定義し、その中にMicroModal.initを記述します。methodsに書いただけでは実行されないので、mounted内でthis.init()を呼び出し、実行するようにします。

<script>
export default {
  mounted() {
    this.init()
  },
  methods: {
    init() {
      MicroModal.init({
        // ここにオプションを書いていく
      })
    },
  },
}
</script>

デモ

以下に簡単なデモを作ってみました。
HTMLとCSSはサンプルのソースコードを調整して使っています。
JavaScriptではオプションにdisableScroll: trueを指定してページのスクロールを無効に、awaitOpenAnimation: trueawaitCloseAnimation: trueを指定してCSSのアニメーションを使ってモーダルを開閉するようにしています。

See the Pen Micromodal.js by tomoyuki nakata (@nakata02576) on CodePen.

最後に

いかがだったでしょうか?
今回はモーダルを作るためにMicromodal.jsを使いましたが、ハンバーガーメニューを作る時にもこのMicromodal.jsを使うとアクセシビリティに配慮したものが簡単に作れます!
よろしければ使ってみてください〜!
以上、中田でした。

参考サイト

https://micromodal.now.sh/
https://coliss.com/articles/build-websites/operation/javascript/tiny-modal-dialogs.html
https://www.willstyle.co.jp/blog/3646/
https://www.hypertextcandy.com/micromodal-js