🍦 Vanilla JS Lightbox

🍦 Vanilla JS Lightbox

Published: 11/28/20203 min read
HTML
CSS
JS

In this post I want to share a simple CSS and Vanilla JS Lightbox I use for some of my projects.
Here is a demo GitHub page: 👉 https://yossi-abramov.github.io/simple-lightbox.github.io/
And the GitHub repository for the project:
👉 https://github.com/yossi-abramov/simple-lightbox.github.io
The HTML for this demo is easy to follow so I will not go over it. Let’s cover the relevant CSS and JS portions of the code.

CSS

Our Lightbox has two states: hidden and visible. Let’s start with the hidden state:

.lightbox{
    opacity: 0;
    visibility: hidden;
    position: fixed;
    left:0;
    right: 0;
    top: 0;
    bottom: 0;
    z-index: -1;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.15s ease-in;
}

As you can see, the Lightbox is in fixed position and all direction properties are set to 0. This makes the Lightbox fill the entire screen without having to use any kind of width or height properties. This positioning strategy can also be very useful in more situations. For example, think of creating an image overlay. You might have an image container positioned relative and a .overly div positioned absolute. By setting all direction properties to 0 you can ensure the image overlay completely fills its parent container.
The styles for the visible state of the Lightbox are pretty simple:

.lightbox.show{
    background-color: rgba(0,0,0, 0.85);
    opacity: 1;
    visibility: visible;
    z-index: 1000;
}

For avoiding a flash of visible Lightbox on page load, it’s important not to set the background-color in the hidden state styles.

JS

The JavaScript for our Lightbox is pretty simple too! In this case, we have three functionalities to cover:

  1. Toggling between visible and hidden Lightbox states
  2. Displaying the subject image in the Lightbox
  3. Hiding the Lightbox on every click that is not on the centered (“subject”) image
document.addEventListener("DOMContentLoaded", () => {

    // ===> DOM elements <=== //

    const $imagesContainer = document.getElementById('images-container');
    const $lightbox = document.getElementById('lightbox');

    // ===> Event listeners and triggers <=== //
    
    // Show lightbox 
    $imagesContainer.addEventListener('click', e => {
        const imageWrapper = e.target.closest('.image-wrapper');

        if (imageWrapper) {
            const image = imageWrapper.querySelector('img');
            if (image) {
                $lightbox.innerHTML = '<div class="close-lightbox"></div>' + image.outerHTML;
                $lightbox.classList.add('show');
            }
        }
    });

    // Hide Lightbox
    $lightbox.addEventListener('click', (e) => {
        if (!e.target.hasAttribute('src')) {
            $lightbox.classList.remove('show');
        }
    });
});

For toggling between hidden and visible states we can add/remove the .show class. We could have used the classList.toggle() method but I find that in this case, using classList.remove() and classList.add() makes the code more readable.
For showing the Lightbox, I didn’t want to use a static image element and to change its src and alt properties separately (think of all the HTML attributes you can have on an image element…). For this reason I’m using image.outerHTML. But, this is just my suggestion for a simple Lightbox and there are many ways to implement it!