Go to homepage

Projects /

Expandable Image Gallery

Image gallery that expands in a modal media gallery on click.

View Demo


How to

The Expandable Image Gallery component allows you to convert your gallery of images in a full-width modal gallery.

To create the demo, we used a simple image gallery based on the CodyHouse framework grid system. You are free to replace the gallery with a different one of your choice (check the Gallery Category for more components).

For it to work properly, make sure to add the following attributes to the container of your gallery:

  • Add the .js-exp-gallery class;
  • Add a data-controls attribute equal to the id of the .exp-lightbox modal (the modal containing the slideshow of images).

In addition to the above, make sure to:

  • Add the .js-exp-gallery__item class to each item of the gallery;
  • Add a data-modal-src attribute to the <img> element inside the .js-exp-gallery equal to the src of the image you want to show in the modal;
  • If you want to add a caption to the image in the modal, add a .js-exp-gallery__caption to the caption element inside the gallery item.

Here's an example of how a gallery item should look like:

 <li class="js-exp-gallery__item">
    <img src="../../../app/assets/img/lightbox-img-2.jpg" data-modal-src="../../../app/assets/img/lightbox-img-hr-2.jpg" alt="Image Description">
    <figcaption class="sr-only js-exp-gallery__caption">Image caption</figcaption>

Note that we added the .sr-only class to the .js-exp-gallery__caption element: this way the caption will only be visible in the modal gallery but it remains accessible to screen readers. 

The modal gallery slideshow is based on the Slideshow component. Some of its features are:

  • Swipe on mobile (left/right to change image, top/bottom to close modal): this is enabled adding a data-swipe='on' to the .exp-lightbox__body element;
  • Keyboard navigation;
  • Lazy loading of images;
  • Image zoom-in/out: this is enabled adding a data-zoom='on' to the .exp-lightbox__body element;
  • Different slide animations: fade effect (add the .slideshow--transition-fade class to the .exp-lightbox__body element) or slide effect (add the .slideshow--transition-slide class).

Lazy loading #

If you want to lazy load the images in the modal gallery, you can add to the .js-exp-gallery element a data-placeholder attribute equal to a placeholder image path (visible while the image is being loaded).

Infinite Scroll #

You can combine the Expandable Image Gallery component with the Infinite Scroll component. For it to work properly, make sure to add the data-container=".js-exp-gallery" to the .js-infinite-scroll element:

<div class="js-infinite-scroll" data-path="/page-{n}.html" data-container=".js-exp-gallery">
  <ul class="exp-gallery grid gap-xs js-exp-gallery" data-controls="expLightbox" data-placeholder="assets/img/expandable-img-gallery-placeholder.svg">
    <li class="col-6 js-exp-gallery__item">
        <!-- gallery img -->

    <!-- other list items here -->

Morphing Images #

The ratio of the gallery images (i.e., the images inside the .js-exp-gallery__item elements) doesn't need to be equal to the one of the modal images (i.e., the images inside the .exp-lightbox component). We've developed a mechanism, based on SVG clipPath and JS-powered transformations, that morphs the original images into the final ones.

If you check the morphing-images variation, you'll notice each figure element uses the aspect-ratio utility class to set a custom ratio for the images.

You can set custom height + width values for the gallery item images, and morph them into modal images with a different size.

Menu Actions #

The modal gallery comes with a menu element that can be used to perform actions (e.g., close modal, download images, etc).

Some of the actions may depend on the selected item in the slideshow. You can use the update-menu  event to detect when a new slide has been selected and update the action buttons:

var menuBar = document.getElementsByClassName('js-menu-bar'); // your menu bar element
if(menuBar.length > 0) {
  menuBar[0].addEventListener('update-menu', function(event){
    // index of the selected item in the slideshow
    // selected <li> item in the slideshow
    // src attribute of the visible <img> item in the slideshow

For example, if you have a download button (e.g., you are using an <a> element with the download attribute), you can update its href using the src attribute of the visible image in the slideshow:

menuBar[0].addEventListener('update-menu', function(event){
  var imgSrc = event.detail.item.querySelector('img').getAttribute('src');
  // downloadBtn is the <a> download button inside the menu bar
  downloadBtn.setAttribute('href', imgSrc);

Demo Assets #

⭐️ Icons by Nucleoapp.

🌅 Demo photos:


Bug report & feedback

Component Github page ↗

Project duplicated

Project created

Globals imported

There was an error while trying to export your project. Please try again or contact us.