Bootstrap 5 の標準機能を使った 脱 JQuery の lightbox
2022 年 1 月改修版
2022年1月改修版
2022年1月に JS 化を行い、CDNで読み込み A タグでパラメータを指定するだけで簡単に Bootstrap の Modal を使った lightbox を実現できるようにしました。
Bootstrap も 2021 年に バージョン 5 がリリースされ、2022 年時点で 5.1 がリリースされています。しかし Bootstrap 5 では バージョン 4 時代と仕様が異なっている点が多くあり、その中のひとつに JQuery が必須でなくなった点が挙げられます。
標準で JQuery が必要なくなるという事で脱 JQuery 志向に則した形にはなったのですが、従来まで利用していたフリーの lightbox プラグインが動作しないケースなどが課題になりました。これは JQuery が必須コンポーネントではなくなったため、JQuery が導入されている事が前提のプログラムが(Bootstrap 5 だけの環境だと)動作しないためであります。
せっかく JQuery を使用しないことで軽量化された環境なので、できたら JQuery を使わずに lightbox っぽい挙動をさせたいと思い、いろいろ調べていたところ、Bootstrap 5 のモーダル (Modal) に「フルスクリーンモーダル」というものが追加されていることに気が付きました。
Modal (モーダル) · Bootstrap v5.0 (getbootstrap.jp)
これをうまくカスタマイズしてあげることで lightbox の代わりにできないかと思い模索を始めました。
実験
まずフルスクリーンモーダルの中に画像を表示させて lightbox っぽい表示にします。そして画像をクリックした際にモーダルが閉じるように画像に data-bs-dismiss=”modal” aria-label=”Close” を加えます。
<a href="#" class="btn btn-primary" role="button" data-bs-toggle="modal" data-bs-target="#lightboxModalFullscreen">画像を表示</a>
<div class="modal fade" id="lightboxModalFullscreen" tabindex="-1" aria-labelledby="lightboxModalFullscreenLabel" aria-hidden="true">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<div class="modal-body">
<img src="/images/dummy.png" class="img-fluid" id="LightboxImage" data-bs-dismiss="modal" aria-label="Close" />
</div>
</div>
</div>
</div>
上記で実行すると、全画面のモーダル上に画像が表示されましたが、画像が左上に表示され、かつ背景が真っ白なので、あまり lightbox っぽくありません。
という訳で上記をカスタマイズしていきましょう。
まず、背景を半透明で暗い lightbox っぽい形に変えます。こちらは Bootstrap の CSS を手書きの CSS で一部上書きすることで解決します。
modal-fullscreen のクラス自体は lightbox っぽい黒の半透明の値を持っているのですが、その上にある modal-content が、白の不透明で上書きをしているため、この modal-content の background-color を無指定にしてあげます。
.modal-content {background-color:unset;}
すると画面上の表示は黒の半透明の背景の上に画像が表示される形になり、lightbox っぽさが増したかと思います。
さて、あとは画像を中央に表示する修正ですが、結論から言うと Bootstrap 5 での flex 関連のクラスをいくつか追加してあげることで実現することができました。modal-body の箇所に d-flex align-items-center justify-content-center を加えることで中央表示が実現できます。
<a href="#" class="btn btn-primary" role="button" data-bs-toggle="modal" data-bs-target="#lightboxModalFullscreen">画像を表示</a>
<div class="modal fade" id="lightboxModalFullscreen" tabindex="-1" aria-labelledby="lightboxModalFullscreenLabel" aria-hidden="true">
<div class="modal-dialog modal-fullscreen" data-bs-dismiss="modal" aria-label="Close">
<div class="modal-content">
<div class="modal-body d-flex align-items-center justify-content-center">
<img src="/images/dummy.png" class="img-fluid" id="LightboxImage" data-bs-dismiss="modal" aria-label="Close" />
</div>
</div>
</div>
</div>
また、画面上の暗い場所をクリックしてもモーダルが閉じるように、modal-fullscreen のある div にも、data-bs-dismiss=”modal” aria-label=”Close” を追加してあげます。これで、黒い所でも画像でも、クリックすると lightbox が閉じる動きになります。
汎用化
以上で lightbox 風の表示はできるようになったのですが、画像ひとつひとつに対して modal を記述するのも非常に面倒なので、プログラム化してひとつの modal でいくつもの画像を lightbox 表示できるようにしたいと思います。
Bootstrap のサイトにはサンプルコードがあるので、それをベースにカスタマイズしていきます。
まず呼び出し側の HTML ですが、A タグで画像サムネイルを囲む一般的な動きを想定して、A で設定したいと思います。
<p><a data-bs-toggle="modal" data-bs-target="#lightboxModalFullscreen" data-bs-lightbox="aaa.jpg" role="button">画像 1</a></p>
<p><a data-bs-toggle="modal" data-bs-target="#lightboxModalFullscreen" data-bs-lightbox="bbb.jpg" role="button">画像 2</a></p>
A のタグにはそれぞれ data-bs-toggle=”modal” という指定と、描画する modal を指定する data-bs-target=”#lightboxModalFullscreen” の指定、および、どの画像を表示したいかという data-bs-lightbox=”(画像のパス)” という値を指定します。
そしてページの下部に以下の JavaScript を追記します。
<script>
var jsCardModal = document.getElementById('lightboxModalFullscreen');
jsCardModal.addEventListener('show.bs.modal', function (event) {
var button = event.relatedTarget
var lightboximage = button.getAttribute('data-bs-lightbox')
document.getElementById('LightboxImage').src = lightboximage;
})
</script>
簡単にいうと、A タグで指定された data-bs-lightbox の値を読み取り、document.getElementById でモーダル内の画像の URL の置き換えを行い、モーダルを表示させるという中身になります。
これで、ひとつのモーダルコードを使いまわすことができます。
Bootstrap 5 モーダル lightbox サンプル
以上で「モダールを使いまわす」コードはできたのですが、「モーダルを書くのも面倒くさい」、「使うときに JS を読み込むだけの、もっと汎用化された形が欲しい」という要望に応えるため、プラグイン化を行いました。
プラグイン
基本的な動きとしては、A タグに data-modal=”bs-lightbox” というデータ属性を追加するだけで、href の画像を Bootstrap 5 の Modal で表示する、という設計になっています。
まず JS を 読み込みます。ページの最後、</BODY> の近くに記載してください。
<script async type="text/javascript" src="https://cdn.jsdelivr.net/gh/avalon-studio/Bootstrap-Lightbox/bs5lightbox.js" crossorigin="anonymous"></script>
そして、サムネイル画像を A タグで括り、A タグに data-modal=”bs-lightbox” というデータ属性を追加します。
<a data-modal="bs-lightbox" href="(lightboxで拡大表示させる画像のURL)" target="_blank"><img src="(サムネイル画像)"></a>
実際に上記コードだけのサンプルページを用意したので、こちらで挙動をご確認ください。
JS プラグイン版 Bootstrap 5 モーダル lightbox サンプル
なお、この JS コードはこちらの Github で公開しています。ご興味がありましたらご覧ください。
avalon-studio/Bootstrap-Lightbox: Simple & lightweight lightbox for Bootstrap 5 (github.com)