JavaScript lightbox effect without using plugins

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
Search for a command to run...

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
It looks so cool and easy thanks for sharing 🤗
Most of you know me for my consistency, a golden arrow in my blog series. I've written 1000 articles in 1008 days! Almost an article a day, and my honeymoon was the only holiday I ever took. I'm super proud of this achievement; it has been a fantasti...

It's not the first time I'll be talking about community. I think it's an essential aspect of any successful tool. This shows in my previous explorations of Astro, Medusa, and now Vendure as well. All these products thrive in a super open, welcoming, ...

The cool part about Vendure is how easy it is to set up and how abstract each layer is. Basically, we get the following elements: External database Server Worker Admin UI Frontend While this is amazing, it also brings a bit of complexity when it co...

The previous article looked at customizing Vendure on a data and process level. In this article, we'll look at customizing emails, as they are often a big part of a webshop system. We'll be looking at two different layers of customization for customi...

Even though Vendure is a pretty significant project out of the box, in some cases, we might want to go in and modify some elements to work to our specific use case. In this article, I'll take a high-level look at some elements we can customize within...

Lightboxes are amazing! I remember the first time seeing them in the jQuery days and thinking, WOW someone spent a lot of time building this.
Over the years, I've come to realise it can be made in Vanilla JavaScript and some CSS.
So today I wanted to show you how you can build your own image Lightbox effect without using any plugins!
A while ago, we did a vanilla javascript modal, which is quite similar but uses a different approach.
The end result is this cool effect:

We will start by laying out the HTML building blocks of our application.
<div class="container">
<div class="col">
<img src="https://images.unsplash.com/photo-1605347220242-04d3b97ceee9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80" onClick="openLightbox(this)" />
</div>
<div class="col">
<img src="https://images.unsplash.com/photo-1605306030698-6e966cc142b4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80" onClick="openLightbox(this)" />
</div>
<div class="col">
<img src="https://images.unsplash.com/photo-1593642634402-b0eb5e2eebc9?ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80" onClick="openLightbox(this)" />
</div>
</div>
<!-- Actual Lightbox -->
<div id="lightbox" class="lightbox hidden">
<div onClick="closeLightbox()" class="close">❌</div>
<div class="lightbox-content">
<img id="lightbox-image" />
</div>
</div>
The top part contains the layout the user will see, in this case a container with three columns, each containing one image.
The image has an onClick function, which calls the openLightbox. (We will create this in a bit)
Then at the bottom, we have the actual Lightbox.
Inside the Lightbox, we add a simple emoji powered close button, which onClick calls the closeLightbox function.
And inside the Lightbox we also see an empty image which we'll use to place our image in.
This article does not focus on accessibility and is not optimized for that purpose
Let's make our application look a little bit better by adding some basic styling to it.
First we will use flexbox to center our columns, and next we add a border and box-shadow to make the image pop more.
.container {
display: flex;
flex-wrap: wrap;
background: url("https://images.unsplash.com/photo-1558051815-0f18e64e6280?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1949&q=80") no-repeat center center;
background-position: cover;
min-height: 100vh;
justify-content: center;
align-items: center;
}
.container .col {
width: 30%;
margin: 1.6%;
}
.container .col img {
cursor: pointer;
border: 5px solid #fff;
box-shadow: 0 0 1rem #aaaaaa;
max-width: 100%;
max-height: 100%;
}
As for our Lightbox goes, we need it to span over the whole page, and be fixed starting from the top.
.lightbox {
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
overflow: auto;
opacity: 1;
visibility: visible;
transition: all 0.3s ease;
}
We are using opacity and visibility so we can animate the fade-in and fade-out effect.
Now let's add the hidden class.
.lightbox.hidden {
opacity: 0;
visibility: hidden;
}
And to top it up we style the button, content and image inside the Lightbox.
.lightbox .close {
position: absolute;
right: 2.5%;
top: 2.5%;
font-size: 2rem;
cursor: pointer;
}
.lightbox-content {
display: flex;
margin: 5%;
align-items: center;
justify-content: center;
}
.lightbox-content img {
max-width: 100%;
max-height: 100%;
border: 5px solid #fff;
}
On to our JavaScript, this is the part that will hook everything up and make it work.
What we want to happen:
Let's define the variables we need to make it work:
const lightbox = document.getElementById('lightbox');
const lightboxHolder = document.getElementById('lightbox-image');
We define our actual Lightbox element, and the image element inside it.
Now let's create the function that will show the Lightbox.
openLightbox = (element) => {
lightboxHolder.src = element.src; lightbox.classList.remove("hidden");
};
Wait, that's it? Yes, we retrieve the src of the image the user clicked on and add it to our Lightbox. Then we remove the hidden class, and the user sees our Lightbox!
Now we just need the close function.
closeLightbox = () => lightbox.classList.add("hidden");
And now we have a fully functional Lightbox, without using any plugins.
You can try this Lightbox out on the following Codepen.
Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter