【超最新版】Micromodal.jsの使い方やモーダルUIの実装方法を徹底解説!

【超最新版】Micromodal.jsの使い方やモーダルUIの実装方法を徹底解説!

この記事を書いた人

もなか

30歳を過ぎてからプログラミングの勉強を独学で始め、現在コーダー3年目。毎日JavaScriptについて勉強中。趣味はパンを焼くこと。2人の男の子のママ。

アクセシビリティのことも考えると、作成が難しいUIがモーダルです。Twitterなどでは「無理に自作せずライブラリに頼ったほうがいい」という声を見かけることが多くなりました。

そこで今回はかんたんにアクセシビリティ対応のモーダルウインドウが実装できる、jQuery非依存の超軽量ライブラリ「Micromodal.js」について詳しく解説します!

特徴やできること、動く仕組みや各オプション、動かない場合のトラブルシューティングなどを網羅的に紹介します。

Micromodal.jsを使ってみようかな…と考えていた方は必見!ぜひ最後までご覧くださいね。

あわせて読みたい

※jQueryでモーダルUIを作る方法についてはこちらで解説してます。
>> 【jQuery】モーダルウィンドウの作り方を解説(コピペ可)

モーダルとは

モーダルウィンドウとは、操作が完了するまで親ウィンドウへの操作を受け付けなくさせるタイプのウィンドウのことである。

モーダルウィンドウが表示されると、その中で指定された操作を完了するかキャンセルするかして、そのウィンドウを閉じない限り、親ウィンドウ側に対する操作ができないようになる。このため、モーダルウィンドウはユーザーに特定の操作をさせたり、確認を促したりといった目的で用いられることが多い。

Weblio 辞書 > コンピュータ > IT用語辞典 > モーダルウィンドウの意味・解説

下の例のように特定の要素をクリックやタップすると、別のコンテンツが浮かび上がって表示されるUI。一度は実装したことある方も多いと思います。

Micromodal.jsとは?

Micromodal.jsは、Webアクセビリティ(a11y)に対応したJavaScript製モーダルライブラリです。

Webアクセシビリティ(a11y)とは

身体的および技術的な制約によらず、Webサイトを使いやすく保つためのベストプラクティスです。

非営利団体W3C(World Wide Web Consortium)が行っているWAI(Web Accessibility Initiative)という取り組みの中で日々議論されています。

※ a11y:AccessibilityのAからYまでの間に11文字が挟まれているため、このように略します。

Micromodal.jsの主な特徴

主な特徴は以下のとおりです。

  • ファイルサイズが軽量(1.9kb)
  • WAI-ARIAガイドラインに準拠
  • jQueryに依存しないピュアなJavaScriptで書かれている
  • キーボード操作が可能
  • 余計なスタイルがあたっていない
  • MITライセンス

Micromodal.jsはWAI-ARIAガイドラインに準拠しているため、Webアクセビリティ(a11y)が保証されています。

CSSが付属されていないのでカスタマイズ性が高く、非常に使いやすいライブラリになっています。

使用する際は、MITライセンスのため無料で自由に利用できますが、著作権を放棄されたわけではありませんので注意しましょう。

MITライセンスとは

MIT ライセンスとは、マサチューセッツ工科大学で作成された代表的なオープンソースライセンスで、無料で自由に使用できます。

使用条件として、再頒布時に著作権表示とライセンス表示を含めることと、作者や著作権者はいかなる責任も負わないことを定めています。

参考:The MIT License|オープンソースライセンスの日本語参考訳 | licenses

Micromodal.jsで出来ること

一部ですが、Micromodal.jsができることは以下のようなものがあります。

  • 背景クリックするとモーダルを閉じる
  • escボタンを押すとモーダルを閉じる
  • モーダルのaria-hidden属性の切り替え
  • モーダル外はTab移動の対象から外す
  • モーダル内の最初のフォーカス可能な要素にフォーカスする
  • モーダルが開いている間は後ろのコンテンツを操作出来ないように背景スクロールを固定する
  • モーダルを閉じた時に、ダイアログを呼び出した要素にフォーカスを戻す

これだけの処理を手軽に実装できる点はとても便利ですね!

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>

Vue.jsの場合

Micromodal.jsをインストールしたあと、micromodal.jsのようなファイルを作成し、以下のようにimport文を記述してください。

import Vue from 'vue'
import * as MicroModal from 'micromodal'
 
Vue.use(MicroModal)

IE11対応

Micromodal.jsはES6記法で書かれており、IE 11 には定義されていないメソッドであるArray.fromObject.assignを使用しています。IE11で使用するにはES6のPolyfillを導入する必要があります。

以下がそれぞれのpolyfillを読み込むコードになります。Micromodal.jsを読み込むよりも前に記述して下さい。

<script src="https://polyfill.io/v3/polyfill.min.js?features=Array.from%2CObject.assign"></script>
<script script src="https://unpkg.com/micromodal/dist/micromodal.min.js"></script>

直接ソースコードに記述したい方は、公式のIssuesをご参照下さい。

Micromodal.jsを使う準備ができたところで、以下からは実際の使い方を解説していきます。

Micromodal.jsの使い方

基本的なHTML構造はこちらです。

<button data-micromodal-trigger="モーダルのid" role="button">モーダルを開く</button>

<div id="modal-1" class="modal" aria-hidden="true"> <!-- ① -->
  <div class="overlay" tabindex="-1" data-micromodal-close> <!-- ② -->
    <div role="dialog" aria-modal="true" aria-labelledby="modal-1-title"> <!-- ③ -->
      <div role="document"><!-- ④ -->
        <header>
          <h2 id="modal-1-title">モーダルタイトル</h2>
          <button aria-label="Close modal" data-micromodal-close></button><!-- ⑤ -->
        </header>

        <div id="modal-1-content">モーダルコンテンツ</div>

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

モーダルを開くボタン(data-micromodal-trigger)

<button data-micromodal-trigger="モーダルのid" role="button">モーダルを開く</button>

モーダルを開くトリガー要素(ボタンやリンク)に、data-micromodal-triggerを付与し、値として対象のモーダルを指定します。

また、モーダルコンテンツの構造には以下の5つのポイントがあります。

  1. モーダル外側のコンテナ要素
  2. モーダルのオーバーレイ
  3. モーダルコンテンツ
  4. モーダルコンテンツのスクリーンリーダー対応
  5. モーダル内の閉じるボタン

①モーダル外側のコンテナ要素(aria-hidden=”true”)

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

モーダルの最も外側のコンテナ要素です。固有のidとaria-hidden=”true”を付与します。

②モーダルのオーバーレイ(data-micromodal-close)

<div class="overlay" tabindex="-1" data-micromodal-close></div>

モーダルのオーバーレイとして機能する要素です。不要な場合は削除してください。data-micromodal-closeを付与することでモーダルを閉じるトリガー要素になります。

③モーダルコンテンツの独立性を主張(role=”dialog”)

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

role=”dialog”は、モーダルのコンテンツがページの他の部分とは別のものであることをスクリーンリーダーなどの支援技術に知らせるために使用します。

④モーダルコンテンツのスクリーンリーダー対応(role=”document”)

<div role="document"><!-- ④ -->
  <div id="modal-1-content">モーダルコンテンツ></div>
</div>

role=”document”はスクリーンリーダーなどの支援技術にモーダル内の文書コンテキストについて知らせるために使用します。

⑤モーダル内の閉じるボタン(data-micromodal-close)

すべてのボタンに、アクションを定義するaria-labelを付与します。閉じるボタンにはdata-micromodal-closeを忘れずに付与します。

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

コンテンツの構造はニーズに合わせて拡張することもできますので、カスタマイズの例として公式のサンプルコードもチェックしてみてください。

公式GitHub:HTMLサンプルコード

CSS

.modal{
  display: none;
}
.modal.is-open {
  display: block;
}

デフォルトのCSSはないので自由にスタイルを当てることが可能ですが、上のコードは最低限必要です。

本記事で紹介するコードは、公式サンプルのCSSを参考にしながらカスタマイズしています。

公式GitHub:CSSサンプルコード

すべて掲載するのは長いため、上のリンク先からコピペして使えます。

JavaScript

モーダルの開閉をどのように制御するかでコードが変わります。

データ属性で制御する場合

データ属性の切り替えをフックとしてモーダルを制御する場合は、以下のコードを記載するだけでMicromodal.jsが実行されます。

MicroModal.init();

JavaScript内で制御する場合

Micromodal.jsには以下の2種類のメソッドが用意されており、JavaScript内で書いたプログラム上でモーダルの制御ができます。

//モーダルを開く
MicroModal.show('モーダルid'); 

//モーダルを閉じる
MicroModal.close('モーダルid');

モーダルの開閉をカスタマイズして使いたい場合に便利ですね!

オプションについて

Micromodal.jsはモーダルの挙動を制御するためのオプションが多数用意されています。

オプション名設定値初期値説明
onShowfunctionモーダルが開いたときに、実行される関数を指定できます。
onClosefunctionモーダルが閉じたときに、実行される関数を指定できます。
openTriggerstringdata-micromodal-triggerモーダルを開くトリガー要素につけるカスタムデータ属性を指定できます。
closeTriggerstringdata-micromodal-closeモーダルを閉じるトリガー要素につけるカスタムデータ属性を指定できます。
openClassstringis-openモーダルが開くときに追加するclass名を指定できます。
disableScrollbooleanfalseモーダルが開いている間、ページスクロールを無効にします。
disableFocusbooleanfalseモーダルが開いたとき、モーダル内の最初のフォーカス可能な要素へのオートフォーカスを無効にします。
awaitOpenAnimationbooleanfalseCSSアニメーションが終了するまで、モーダル内要素のフォーカスを待ちます。
awaitCloseAnimationbooleanfalseCSSアニメーションが終わるのを待ってから、モーダル内要素を非表示にします。
debugModebooleanfalseコンソールに表示される警告を抑制します。
オプション一覧

オプションはオブジェクトを渡すことで指定できます。

指定しなくても動きますが、アクセシビリティのことを考えるとdisableScrollは必須にしておくといいかもしれません。

MicroModal.init({
  disableScroll: true,//モーダルが開いている間、ページスクロールを無効にします。
});

導入から実際に動かすところまで、とても手軽でしたね!

次からはMicromodal.jsの動く仕組みを図解を交えて解説します!

Micromodal.jsの動く仕組み

Micromodal.jsの挙動は非常にシンプルで、以下2点のみとなります。

  1. aria-hiddenの値を切り替える
  2. aria-hiddenの値によって .is-openをつけ外しする

aria-hidden=”true”の場合

aria-hidden="true"の場合はMicromodal.jsが.is-openを外します。CSSにはモーダル要素を非表示にするスタイルを指定しましょう。

<div id="modal-1" class="micromodal-slide" aria-hidden="true"><!-- モーダルコンテンツ --></div>
モーダルが閉じているとき
モーダルが閉じているときの様子

data-micromodal-triggerが付与された要素をクリックすると、aria-hidden="false"に値が変わります。

aria-hidden=”false”の場合

aria-hidden="false"の場合はMicromodal.jsが.is-openを付与します。

このときCSSにはモーダル要素を表示するスタイルを指定しましょう。

<div id="modal-1" class="micromodal-slide is-open" aria-hidden="false"><!-- モーダルコンテンツ --></div>
モーダルが開いているとき
モーダルが開いているときの様子

data-micromodal-closeが付与された要素をクリックすると、aria-hidden="true"に値が変わります。

Micromodal.jsを使ったサンプル

モーダルを開いたら背景固定

スクロールを固定するにはdisableScrollオプションを指定します。

MicroModal.init({ disableScroll: true });

サンプルではひとつのセクション長さを90vhとしていますが、モーダルが出現している間はスクロールできなくなっています。

同一ページ内に複数のモーダルを設置

複数モーダルを設置する際はモーダルそれぞれに固有のidを付与し、モーダルを開くボタンにidを紐付けます。

<button
  class="modal__btn modal__btn-primary"
  data-micromodal-trigger="modal-1"
  role="button"
>
  モーダル1
</button>
<button
  class="modal__btn modal__btn-primary"
  data-micromodal-trigger="modal-2"
  role="button"
>
  モーダル2
</button>
<button
  class="modal__btn modal__btn-primary"
  data-micromodal-trigger="modal-3"
  role="button"
>
  モーダル3
</button>

<div id="modal-1" aria-hidden="true"><!-- モーダルコンテンツ --></div>
<div id="modal-2" aria-hidden="true"><!-- モーダルコンテンツ --></div>
<div id="modal-3" aria-hidden="true"><!-- モーダルコンテンツ --></div>

クリックした画像がポップアップされる

上のコードを応用したギャラリーです。画像をクリックすると、クリックした画像がポップアップされます。

モーダルを閉じた際にモーダル内動画も停止させる

const pauseVideo = () => {
  document.querySelector("video").pause(); //video要素を取得し、動画を停止する
};

MicroModal.init({
  awaitCloseAnimation: true,
  awaitOpenAnimation: true,
  onClose: pauseVideo //モーダルを閉じるときにpauseVideoを実行する
});

モーダルを閉じた際にモーダル内の動画も停止させるには、onShowプロパティを用いて、モーダルを開いたときに「動画を停止する処理」を追加します。

ハンバーガーメニューの実装

ボタンを押したらナビゲーションメニューが画面外からスッと出てくるおなじみのUI。

メニューを開いた時、ボタンかオーバーレイ(暗くなっている部分)をクリックするとメニューが閉じるような、一般的な仕様もMicromodal.jsで実現できます。

WAI-ARIAの中で、コンテンツの展開状態を表すaria-expandedがあります。

アクセシビリティを考慮するならば、aria-expandedを開閉の条件(フック)にすることが望ましいですが、現在Firefoxブラウザに対応していません(2022年8月)

Firefoxも2023年10月24日にリリースされたバージョン119で、aria-expandedに対応しました。

ariaExpandedのブラウザ対応状況
ariaExpanded | Can I use

ハンバーガーメニューはモーダルの開閉を一つのbutton要素で行う必要があるため、showメソッド・closeメソッドを用いて実装しています。

const button = document.getElementById("buttonHamburger");
const modal = document.getElementById("modal-1");

button.addEventListener("click", () => {
  if (modal.classList.contains("is-open")) {
    button.classList.remove("is-open");
    button.ariaExpanded = true;
    MicroModal.close("modal-1", { // モーダルを閉じる処理
      awaitCloseAnimation: true // 開閉時のアニメーションを可能に
    });
  } else {
    button.classList.add("is-open");
    button.ariaExpanded = false;
    MicroModal.show("modal-1", { // モーダルを開く処理
      disableScroll: true, // ページスクロールを無効に
      awaitOpenAnimation: true, // 開閉時のアニメーションを可能に
      onClose: () => {
        button.classList.remove("is-open"); // 閉じたときハンバーガーボタンのスタイルを戻す
      }
    });
  }
});

ハンバーガーメニューの動く仕組みは以下のとおりです。

ハンバーガーメニューの動く仕組み
ハンバーガーメニューの動く仕組み

aria-hidden="ture"のときはモーダル内のメニューを画面外へずらして設置しaria-hidden="false"でメニューがコンテンツ部分に被るように指定しています。

ハンバーガーボタンのデザインや、細かい動きのロジックは以下の記事で詳しく解説しています。こちらもぜひチェックしてみてください!

ボタンデザインが変わらない時は…?

サンプルを作るためにコードを書いていると、オーバーレイ部分をクリックしてもハンバーガーメニューのボタンデザインが変わらないという現象が起こりました。

いろいろ検証していると、JavaScriptでCSSのつけ外しを制御していることが原因だとわかりましたので、ポイントを紹介します。

上のサンプルでは、オーバーレイをクリックしてもボタンデザインは変わりません。

この要因は、デフォルトのdata-micromodal-triggerdata-micromodal-closeをフックにして動く動作とは連動しないことで起こっているようでした。

jsファイルの違い
jsコードの違い

画像右のコードは正常に動作するコードです(上で紹介したコードと同じ)。

モーダルが閉じるタイミングで実行されるMicromodal.jsオプションのonCloseを使い、jsのclassListプロパティとremoveメソッドを書いて、ボタンに付与されたis-openクラスを削除することで解決しました。

JavaScript側からMicromodal.jsを動かす際には、ハンバーガーボタンを押したときのクリックイベント内に定義しているModal.showの中で、さらにオプションを定義しないとダメだったようです。

公式にも詳しく書かれていなかったため注意しましょう!

スライダー要素クリック時にモーダルを開く

上の例では、最初のスライダー要素をクリックするとモーダルが開きます。(今回のスライダーはカンタンに実装できるプラグイン「splide」を使用しています)

//splideの設定
const options = {
  cover: true,
  heightRatio: 0.5
};
const splide = new Splide(".splide", options);
splide.mount();

//micromodalの設定
MicroModal.init({ awaitCloseAnimation: true, awaitOpenAnimation: true });

スライダーとモーダルに関連するコードは上記のコードのみ。とてもシンプルですね!

スライダープラグインの「splide」については以下の記事で詳しく解説していますので、あわせてチェックしてみてください!

モーダル内にスライダー要素を実装

スライダープラグイン「splide」と併用したパターンをもうひとつ。今度は開いたモーダルの中にスライダー要素を実装するパターンです。

こちらを実装するには注意するポイントがあります。

splideで高さを揃えると正常に動かない時の対処

splideはjs側で画像の高さを揃えるcoverオプションを渡すことが可能ですが、こちらを指定するとMicromodal.jsが正常に動作しませんでした。

splideが生成するはずの高さが画像に適用されていないため、モーダルボタンを押しても画像が表示されていません。

ブラウザの幅を変えるとsplideが動くのか、高さが適用され画像が表示されます。

//splideの設定
const options = {
//以下のオプションを指定するとスライダーのレイアウトが崩れてしまう
  cover: true, //画像のsrcをその親要素のbackground-imageに変換するかを指定
  heightRatio: 0.7 //スライドの高さをスライダーの幅に対する割合で指定
};
const splide = new Splide(".splide", options);
splide.mount();

//micromodalの設定
MicroModal.init({ awaitCloseAnimation: true, awaitOpenAnimation: true });

この現象の対策は、スライダーの画像高さをCSSで指定することです。

img{
  width:100%;
  height:100%;
  object-fit:cover;
}

splideにオプションを渡すのではなく、上のようにCSS側で制御すると正常に動作しました。

Micromodal.jsとsplideを併用するときは上記の点に気をつけて実装しましょう。

まとめ

アクセシビリティなモーダルを自作しようとすると、tabやescなどのキーボードの操作や、WAI-ARIAのことも考えなければならず、とても時間がかかりそうです。

今後モーダルを実装する際には、ぜひ今回ご紹介したMicromodal.jsを使いながら、効率よく実装を進めていきましょう!

また、モーダルと似たUIにLightbox(ポップアップ)がありますが、こちらをカンタンに実装できるライブラリ「Luminous」について解説している記事もあるので、チェックしてみてください!