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:
- Toggling between visible and hidden Lightbox states
- Displaying the subject image in the Lightbox
- 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!