Bootstrap 5 の標準機能を使った lightbox

Bootstrap 5 の標準機能を使った lightbox

Bootstrap も 2021 年 5 月時点でベータ 3 になっており、近日中には正式バージョンが公開されるのではないかと思っております。

私の方でも実験などをしておりますが、フリーの lightbox プラグインが動作しないケースなどが見受けられました。これは、Bootstrap 5 では仕様が変更になり 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 サンプル

注意:上記は Bootstrap 5.0 Beta 3 で挙動を確認したものになります。5.0 正式版時にはもしかしたら挙動が変わる部分があるかもしれませんので、あらかじめご留意ください。