Bootstrap 5 Image Gallery Lightbox

Bootstrap 5 Image Gallery Lightbox
Code Snippet:Bootstrap 5 Lightbox Gallery
Demo URL:View Demo
Download Link:Download
Author:Adorade
Official Website:Visit Website

This code creates a stylish image gallery using Bootstrap 5, featuring a lightbox effect. When you click an image, it opens in a full-screen modal with navigation controls. This is achieved using HTML for structure, CSS for styling, and JavaScript for interactive functionality.

The gallery supports full-screen mode, making it easy to view images in detail. This code is perfect for displaying images beautifully on your website.

How to Create Bootstrap 5 Image Gallery Lightbox

1. First, you need to include Bootstrap 5 in your project. Add the following CDN links in the <head> section of your HTML file.

<!-- Bootstrap 5 CSS -->
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css'>
<!-- Bootstrap 5 JS -->
<script src='https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js'></script>

2. Next, add the HTML structure for your image gallery. This includes a heading, a description, and the gallery grid. Similarly, create a modal that will display the images in full screen. Add this code at the end of your HTML file.

<svg class="d-none" xmlns="http://www.w3.org/2000/svg">
  <symbol id="enlarge" viewBox="0 0 16 16">
    <path d="M1.5 1a.5.5 0 0 0-.5.5v4a.5.5 0 0 1-1 0v-4A1.5 1.5 0 0 1 1.5 0h4a.5.5 0 0 1 0 1h-4zM10 .5a.5.5 0 0 1 .5-.5h4A1.5 1.5 0 0 1 16 1.5v4a.5.5 0 0 1-1 0v-4a.5.5 0 0 0-.5-.5h-4a.5.5 0 0 1-.5-.5zM.5 10a.5.5 0 0 1 .5.5v4a.5.5 0 0 0 .5.5h4a.5.5 0 0 1 0 1h-4A1.5 1.5 0 0 1 0 14.5v-4a.5.5 0 0 1 .5-.5zm15 0a.5.5 0 0 1 .5.5v4a1.5 1.5 0 0 1-1.5 1.5h-4a.5.5 0 0 1 0-1h4a.5.5 0 0 0 .5-.5v-4a.5.5 0 0 1 .5-.5z"/>
  </symbol>
  <symbol id="exit" viewBox="0 0 16 16">
    <path d="M5.5 0a.5.5 0 0 1 .5.5v4A1.5 1.5 0 0 1 4.5 6h-4a.5.5 0 0 1 0-1h4a.5.5 0 0 0 .5-.5v-4a.5.5 0 0 1 .5-.5zm5 0a.5.5 0 0 1 .5.5v4a.5.5 0 0 0 .5.5h4a.5.5 0 0 1 0 1h-4A1.5 1.5 0 0 1 10 4.5v-4a.5.5 0 0 1 .5-.5zM0 10.5a.5.5 0 0 1 .5-.5h4A1.5 1.5 0 0 1 6 11.5v4a.5.5 0 0 1-1 0v-4a.5.5 0 0 0-.5-.5h-4a.5.5 0 0 1-.5-.5zm10 1a1.5 1.5 0 0 1 1.5-1.5h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 0-.5.5v4a.5.5 0 0 1-1 0v-4z"/>
  </symbol>
</svg>

<h1 class="text-center mb-0">Bootstrap 5 Lightbox Gallery</h1>
<p class="text-center mb-4">Click an image to reveal the lightbox</p>

<section class="photo-gallery">
  <div class="container">
    <div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4 gallery-grid">
      <div class="col">
        <a class="gallery-item" href="https://picsum.photos/id/251/1200/800.webp">
          <img src="https://picsum.photos/id/251/480/320.webp" class="img-fluid" alt="Lorem ipsum dolor sit amet">
        </a>
      </div>
      <div class="col">
        <a class="gallery-item" href="https://picsum.photos/id/678/1200/800.webp">
          <img src="https://picsum.photos/id/678/480/320.webp" class="img-fluid" alt="Ipsum lorem dolor sit amet">
        </a>
      </div>
      <div class="col">
        <a class="gallery-item" href="https://picsum.photos/id/74/1200/800.webp">
          <img src="https://picsum.photos/id/74/480/320.webp" class="img-fluid" alt="Dolor lorem ipsum sit amet">
        </a>
      </div>
      <div class="col">
        <a class="gallery-item" href="https://picsum.photos/id/92/1200/800.webp">
          <img src="https://picsum.photos/id/92/480/320.webp" class="img-fluid" alt="Sit amet lorem ipsum dolor">
        </a>
      </div>
      <div class="col">
        <a class="gallery-item" href="https://picsum.photos/id/62/1200/800.webp">
          <img src="https://picsum.photos/id/62/480/320.webp" class="img-fluid" alt="Aut ipsam deserunt nostrum quo">
        </a>
      </div>
      <div class="col">
        <a class="gallery-item" href="https://picsum.photos/id/575/1200/800.webp">
          <img src="https://picsum.photos/id/575/480/320.webp" class="img-fluid" alt="Nulla ex nihil eligendi tempora">
        </a>
      </div>
      <div class="col">
        <a class="gallery-item" href="https://picsum.photos/id/110/1200/800.webp">
          <img src="https://picsum.photos/id/110/480/320.webp" class="img-fluid" alt="Nemo perspiciatis voluptatum">
        </a>
      </div>
      <div class="col">
        <a class="gallery-item" href="https://picsum.photos/id/177/1200/800.webp">
          <img src="https://picsum.photos/id/177/480/320.webp" class="img-fluid" alt="Accusantium consequuntur modi">
        </a>
      </div>
      <div class="col">
        <a class="gallery-item" href="https://picsum.photos/id/197/1200/800.webp">
          <img src="https://picsum.photos/id/197/480/320.webp" class="img-fluid" alt="Dolore asperiores reprehenderit">
        </a>
      </div>
    </div>
  </div>
</section>

<footer id="copyright" class="mt-5 text-center">
  <div class="container">
    <div class="row">
      <div class="col">
        <p class="mb-0">With <b>Bootstrap 5.3.2</b> and <b>Vanilla JS</b></p>
        <p class="mb-0">Photos source: <a target="_blank" href="https://picsum.photos">Picsum photos</a></p>
        <p class="mb-0">Code made by <a target="_blank" href="https://adorade.ro">Adorade</a>. License <b>MIT</b></p>
      </div>
    </div>
  </div>
</footer>

<div class="modal fade lightbox-modal" id="lightbox-modal" tabindex="-1">
  <div class="modal-dialog modal-dialog-centered modal-fullscreen">
    <div class="modal-content">
      <button type="button" class="btn-fullscreen-enlarge" aria-label="Enlarge fullscreen">
        <svg class="bi"><use href="#enlarge"></use></svg>
      </button>
      <button type="button" class="btn-fullscreen-exit d-none" aria-label="Exit fullscreen">
        <svg class="bi"><use href="#exit"></use></svg>
      </button>
      <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      <div class="modal-body">
        <div class="lightbox-content">
          <!-- JS content here -->
        </div>
      </div>
    </div>
  </div>
</div>

3. Add the following CSS to style the gallery and modal. You can include this in your CSS file or inside a <style> tag in the <head> section.

:root {
  --lightbox: rgb(0 0 0 / 0.75);
  --carousel-text: #fff;
}


body {
  margin: 1.5rem 0 3.5rem;
}

@keyframes zoomin {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.05);
  }
  100% {
    transform: scale(1);
  }
}

.gallery-item {
  display: block;
}

.gallery-item img {
  box-shadow: 0 1rem 1rem rgba(0, 0, 0, 0.15);
  transition: box-shadow 0.2s;
}

.gallery-item:hover img {
  box-shadow: 0 1rem 1rem rgba(0, 0, 0, 0.35);
}

.lightbox-modal .modal-content {
  background-color: var(--lightbox);
}

.lightbox-modal .btn-close {
  position: absolute;
  top: 1.25rem;
  right: 1.25rem;
  font-size: 1.25rem;
  z-index: 10;
  filter: invert(1) grayscale(100);
}

.lightbox-modal .modal-body {
  display: flex;
  align-items: center;
  padding: 0;
}

.lightbox-modal .lightbox-content {
  width: 100%;
}

.lightbox-modal .carousel-indicators {
  margin-bottom: 0;
}

.lightbox-modal .carousel-indicators [data-bs-target] {
  background-color: var(--carousel-text) !important;
}

.lightbox-modal .carousel-inner {
  width: 75%;
}

.lightbox-modal .carousel-inner img {
  animation: zoomin 10s linear infinite;
}

.lightbox-modal .carousel-item .carousel-caption {
  right: 0;
  bottom: 0;
  left: 0;
  padding-bottom: 2rem;
  background-color: var(--lightbox);
  color: var(--carousel-text) !important;
}

.lightbox-modal .carousel-control-prev,
.lightbox-modal .carousel-control-next {
  width: auto;
}

.lightbox-modal .carousel-control-prev {
  left: 1.25rem;
}

.lightbox-modal .carousel-control-next {
  right: 1.25rem;
}

@media (min-width: 1400px) {
  .lightbox-modal .carousel-inner {
    max-width: 60%;
  }
}

[data-bs-theme = "dark"] .lightbox-modal .carousel-control-next-icon,
[data-bs-theme = "dark"] .lightbox-modal .carousel-control-prev-icon {
    filter: none;
}

.btn-fullscreen-enlarge,
.btn-fullscreen-exit {
  position: absolute;
  top: 1.25rem;
  right: 3.5rem;
  z-index: 10;
  border: 0;
  background: transparent;
  opacity: .6;
  font-size: 1.25rem;
}

.bi {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.035em;
  fill: currentcolor;
}

4. Finally, create a gallery.js file to handle the JavaScript functionality for the lightbox. This script dynamically generates gallery items and initializes the lightbox when an image is clicked.

const html = document.querySelector('html');
html.setAttribute('data-bs-theme', 'dark');

document.addEventListener('DOMContentLoaded', () => {
  // --- Create LightBox
  const galleryGrid = document.querySelector(".gallery-grid");
  const links = galleryGrid.querySelectorAll("a");
  const imgs = galleryGrid.querySelectorAll("img");
  const lightboxModal = document.getElementById("lightbox-modal");
  const bsModal = new bootstrap.Modal(lightboxModal);
  const modalBody = lightboxModal.querySelector(".lightbox-content");

  function createCaption (caption) {
    return `<div class="carousel-caption d-none d-md-block">
        <h4 class="m-0">${caption}</h4>
      </div>`;
  }

  function createIndicators (img) {
    let markup = "", i, len;

    const countSlides = links.length;
    const parentCol = img.closest('.col');
    const curIndex = [...parentCol.parentElement.children].indexOf(parentCol);

    for (i = 0, len = countSlides; i < len; i++) {
      markup += `
        <button type="button" data-bs-target="#lightboxCarousel"
          data-bs-slide-to="${i}"
          ${i === curIndex ? 'class="active" aria-current="true"' : ''}
          aria-label="Slide ${i + 1}">
        </button>`;
    }

    return markup;
  }

  function createSlides (img) {
    let markup = "";
    const currentImgSrc = img.closest('.gallery-item').getAttribute("href");

    for (const img of imgs) {
      const imgSrc = img.closest('.gallery-item').getAttribute("href");
      const imgAlt = img.getAttribute("alt");

      markup += `
        <div class="carousel-item${currentImgSrc === imgSrc ? " active" : ""}">
          <img class="d-block img-fluid w-100" src=${imgSrc} alt="${imgAlt}">
          ${imgAlt ? createCaption(imgAlt) : ""}
        </div>`;
    }

    return markup;
  }

  function createCarousel (img) {
    const markup = `
      <!-- Lightbox Carousel -->
      <div id="lightboxCarousel" class="carousel slide carousel-fade" data-bs-ride="true">
        <!-- Indicators/dots -->
        <div class="carousel-indicators">
          ${createIndicators(img)}
        </div>
        <!-- Wrapper for Slides -->
        <div class="carousel-inner justify-content-center mx-auto">
          ${createSlides(img)}
        </div>
        <!-- Controls/icons -->
        <button class="carousel-control-prev" type="button" data-bs-target="#lightboxCarousel" data-bs-slide="prev">
          <span class="carousel-control-prev-icon" aria-hidden="true"></span>
          <span class="visually-hidden">Previous</span>
        </button>
        <button class="carousel-control-next" type="button" data-bs-target="#lightboxCarousel" data-bs-slide="next">
          <span class="carousel-control-next-icon" aria-hidden="true"></span>
          <span class="visually-hidden">Next</span>
        </button>
      </div>
      `;

    modalBody.innerHTML = markup;
  }

  for (const link of links) {
    link.addEventListener("click", function (e) {
      e.preventDefault();
      const currentImg = link.querySelector("img");
      const lightboxCarousel = document.getElementById("lightboxCarousel");

      if (lightboxCarousel) {
        const parentCol = link.closest('.col');
        const index = [...parentCol.parentElement.children].indexOf(parentCol);

        const bsCarousel = new bootstrap.Carousel(lightboxCarousel);
        bsCarousel.to(index);
      } else {
        createCarousel(currentImg);
      }

      bsModal.show();
    });
  }

  // --- Support Fullscreen
  const fsEnlarge = document.querySelector(".btn-fullscreen-enlarge");
  const fsExit = document.querySelector(".btn-fullscreen-exit");

  function enterFS () {
    lightboxModal.requestFullscreen().then({}).catch(err => {
      alert(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
    });
    fsEnlarge.classList.toggle("d-none");
    fsExit.classList.toggle("d-none");
  }

  function exitFS () {
    document.exitFullscreen();
    fsExit.classList.toggle("d-none");
    fsEnlarge.classList.toggle("d-none");
  }

  fsEnlarge.addEventListener("click", (e) => {
    e.preventDefault();
    enterFS();
  });

  fsExit.addEventListener("click", (e) => {
    e.preventDefault();
    exitFS();
  });
})

Test your gallery in different browsers and devices to ensure it displays correctly. Customize the gallery by adding more images or adjusting CSS styles to match your website’s design.

That’s all! hopefully, you have successfully created an Image Gallery with Lightbox on your website. If you have any questions or suggestions, feel free to comment below.

Leave a Reply

Your email address will not be published. Required fields are marked *