1. Web Design
  2. HTML/CSS
  3. Bootstrap

How to Build a Responsive Bootstrap Lightbox Gallery

Scroll to top
Read Time: 7 min

It’s time for another handy Bootstrap extension, folks! Today, we’ll build something that I’m sure many of you wish was integrated into Bootstrap by default: a responsive lightbox gallery.

How many times have you needed to add a responsive lightbox gallery to a Bootstrap project? In such a situation you might have tried an external JavaScript plugin like PhotoSwipe. However, you can create a simple yet fully functional responsive lightbox gallery by taking advantage of existing Bootstrap components. This tutorial will show you how to achieve this with minimal effort.

Although not required, good knowledge of Bootstrap will be beneficial to follow along with this tutorial.

Our Responsive Bootstrap Lightbox Extension

Without further ado, here’s what we’ll be creating (click an image to open the lightbox):

Get Thousands of Bootstrap Templates on Envato Elements

Check out Envato Elements for a huge collection of Bootstrap templates, website designs, and Bootstrap-based WordPress themes—unlimited downloads with your monthly subscription!

Bootstrap Templates on Envato ElementsBootstrap Templates on Envato ElementsBootstrap Templates on Envato Elements
Premium Bootstrap templates with your Envato Elements subscription

1. Define the HTML Markup

Create an Image Grid

To begin with, we’ll create an image grid to reveal the beauty of Ireland through some Unsplash images. To do this, we’ll take advantage of Bootstrap’s grid system.

All images should have the same dimensions. In our case, we’ll work with big ones (1920px x 1280px). These will appear as soon as the lightbox opens.

The image gridThe image gridThe image grid

Here’s the required structure for our grid:

1
<section class="image-grid">
2
  <div class="container-xxl">
3
    <div class="row gy-4">
4
      <div class="col-12 col-sm-6 col-md-4">
5
        <figure>
6
          <a class="d-block" href="">
7
            <img width="1920" height="1280" src="ireland1.jpg" class="img-fluid" alt="Ring of Kerry, County Kerry, Ireland" data-caption="Ring of Kerry, County Kerry, Ireland">
8
          </a>
9
        </figure>
10
      </div>
11
      <div class="col-12 col-sm-6 col-md-4">
12
        <figure>
13
          <a class="d-block" href="">
14
            <img width="1920" height="1280" src="ireland2.jpg" class="img-fluid" alt="Fintown, Ireland" data-caption="Fintown, Ireland">
15
          </a>
16
        </figure>
17
      </div>
18
      <!-- more columns here -->
19
    </div>
20
  </div>
21
</section>

Build the Modal Skeleton

We’ll continue by specifying a part of the markup needed for registering a full-screen Bootstrap modal. Its main content will be created dynamically and hold a Bootstrap carousel. 

1
<div class="modal lightbox-modal" id="lightbox-modal" tabindex="-1">
2
  <div class="modal-dialog modal-fullscreen">
3
    <div class="modal-content">
4
      <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
5
      <div class="modal-body">
6
        <div class="container-fluid p-0">
7
          <!-- JS content here -->
8
        </div>
9
      </div>
10
    </div>
11
  </div>
12
</div>

2. Add Some Styles

Coming up next, we’ll add some styles for our project.

Most importantly:

  • The Bootstrap lightbox images will have a maximum height equal to the viewport height. Additionally, we’ll set their width to auto.
  • The carousel controls will be vertically centered, and their height won’t be equal to the carousel height (as happens by default with Bootstrap carousels). We do this because there will be an extra close button on the top right of the lightbox.

Here are the associated styles:

1
/* BASIC STYLES

2
–––––––––––––––––––––––––––––––––––––––––––––––––– */
3
:root {
4
  --lightbox: #242424;
5
}
6
7
body {
8
  margin: 24px 0 48px;
9
  font: 20px / 28px "Marck Script", cursive;
10
}
11
12
/* IMAGE GRID STYLES

13
–––––––––––––––––––––––––––––––––––––––––––––––––– */
14
.image-grid figure {
15
  margin-bottom: 0;
16
}
17
18
.image-grid img {
19
  box-shadow: 0 1rem 1rem rgba(0, 0, 0, 0.15);
20
  transition: box-shadow 0.2s;
21
}
22
23
.image-grid a:hover img {
24
  box-shadow: 0 1rem 1rem rgba(0, 0, 0, 0.35);
25
}
26
27
/* LIGHTBOX STYLES

28
–––––––––––––––––––––––––––––––––––––––––––––––––– */
29
.lightbox-modal .modal-content {
30
  background: var(--lightbox);
31
}
32
33
.lightbox-modal .btn-close {
34
  position: absolute;
35
  top: 20px;
36
  right: 18px;
37
  font-size: 1.2rem;
38
  z-index: 10;
39
}
40
41
.lightbox-modal .modal-body {
42
  display: flex;
43
  align-items: center;
44
  padding: 0;
45
  text-align: center;
46
}
47
48
.lightbox-modal img {
49
  width: auto;
50
  max-height: 100vh;
51
  max-width: 100%;
52
}
53
54
.lightbox-modal .carousel-caption {
55
  left: 0;
56
  right: 0;
57
  bottom: 0;
58
  background: rgba(36, 36, 36, 0.75);
59
}
60
61
.lightbox-modal .carousel-control-prev,
62
.lightbox-modal .carousel-control-next {
63
  top: 50%;
64
  bottom: auto;
65
  transform: translateY(-50%);
66
  width: auto;
67
}
68
69
.lightbox-modal .carousel-control-prev {
70
  left: 10px;
71
}
72
73
.lightbox-modal .carousel-control-next {
74
  right: 10px;
75
}

3. Create the Bootstrap Lightbox

Each time we click on a link, the modal will appear and contain a carousel. By combining the modal and carousel Bootstrap components, we can produce a solid lightbox gallery that will be responsive and support swipe and keyboard navigations.

The carousel markupThe carousel markupThe carousel markup

Here are some things for consideration:

  • We’ll generate the carousel markup only the very first time someone clicks on a link.
  • Every other time, there’s no need to recreate it and perform unnecessary actions. At that point, we’ll only need to use the carousel’s to() method for navigating directly to the appropriate slide.
  • The carousel won’t autoplay and its slides will change with a fade animation. 
  • Each slide will have an optional caption that will be determined by the data-caption attribute of the associated image. If an image doesn’t need a caption on the lightbox, just don’t place such an attribute. Note that we use a custom attribute instead of the default alt one for the image caption. The reason being that the first one is optional and might contain more detailed text compared to the second one that is always good to exist for accessibility reasons. But, you’re free to customize this behavior if you want.
  • The carousel images won’t contain the d-block and w-100 classes that exist on all Bootstrap code examples.

With all the above in mind, here’s the associated JavaScript code:

1
const imageGrid = document.querySelector(".image-grid");
2
const links = imageGrid.querySelectorAll("a");
3
const imgs = imageGrid.querySelectorAll("img");
4
const lightboxModal = document.getElementById("lightbox-modal");
5
const bsModal = new bootstrap.Modal(lightboxModal);
6
const modalBody = document.querySelector(".modal-body .container-fluid");
7
8
for (const link of links) {
9
  link.addEventListener("click", function (e) {
10
    e.preventDefault();
11
    const currentImg = link.querySelector("img");
12
    const lightboxCarousel = document.getElementById("lightboxCarousel");
13
    if (lightboxCarousel) {
14
      const parentCol = link.parentElement.parentElement;
15
      const index = [...parentCol.parentElement.children].indexOf(parentCol);
16
      const bsCarousel = new bootstrap.Carousel(lightboxCarousel);
17
      bsCarousel.to(index);
18
    } else {
19
      createCarousel(currentImg);
20
    }
21
    bsModal.show();
22
  });
23
}
24
25
function createCarousel(img) {
26
  const markup = `

27
    <div id="lightboxCarousel" class="carousel slide carousel-fade" data-bs-ride="carousel" data-bs-interval="false">

28
      <div class="carousel-inner">

29
        ${createSlides(img)}

30
      </div> 

31
      <button class="carousel-control-prev" type="button" data-bs-target="#lightboxCarousel" data-bs-slide="prev">

32
       <span class="carousel-control-prev-icon" aria-hidden="true"></span>

33
       <span class="visually-hidden">Previous</span>

34
      </button>

35
      <button class="carousel-control-next" type="button" data-bs-target="#lightboxCarousel" data-bs-slide="next">

36
        <span class="carousel-control-next-icon" aria-hidden="true"></span>

37
        <span class="visually-hidden">Next</span>

38
      </button>

39
    </div>

40
    `;
41
42
  modalBody.innerHTML = markup;
43
}
44
45
function createSlides(img) {
46
  let markup = "";
47
  const currentImgSrc = img.getAttribute("src");
48
49
  for (const img of imgs) {
50
    const imgSrc = img.getAttribute("src");
51
    const imgAlt = img.getAttribute("alt");
52
    const imgCaption = img.getAttribute("data-caption");
53
54
    markup += `

55
    <div class="carousel-item${currentImgSrc === imgSrc ? " active" : ""}">

56
      <img src=${imgSrc} alt=${imgAlt}>

57
      ${imgCaption ? createCaption(imgCaption) : ""}

58
    </div>

59
    `;
60
  }
61
62
  return markup;
63
}
64
65
function createCaption(caption) {
66
  return `<div class="carousel-caption">

67
     <p class="m-0">${caption}</p>

68
    </div>`;
69
}

Our Responsive Bootstrap Lightbox is Complete!

That concludes another Bootstrap customization, folks! During this short journey, we first built an image grid and then covered the creation of a responsive lightbox gallery. Crucially, we created this lightbox by customizing only slightly existing Bootstrap components. I hope this has inspired you to create even more powerful Bootstrap lightboxes.

For optimal results, be sure to use images with equal dimensions, or else you’ll notice a small jump when the active slide changes.

Once again, here’s what we built:

If you want to go even further and familiarize yourselves with building custom lightboxes, have a look at another recent tutorial.

As always, thanks a lot for reading!

Learn to Customize Bootstrap Yourself

We’ve covered a lot of Bootstrap customizations over the years; take a look yourself!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.