JavaScript lightbox effect without using plugins

JavaScript lightbox effect without using plugins

Chris Bongers
·Nov 19, 2020·

6 min read

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:

Vanilla JavaScript Lightbox

HTML Structure

We will start by laying out the HTML building blocks of our application.

<div class="container">
  <div class="col">
    <img src="" onClick="openLightbox(this)" />
  <div class="col">
    <img src="" onClick="openLightbox(this)" />
  <div class="col">
    <img src="" onClick="openLightbox(this)" />

<!-- Actual Lightbox -->
<div id="lightbox" class="lightbox hidden">
  <div onClick="closeLightbox()" class="close"></div>
  <div class="lightbox-content">
    <img id="lightbox-image" />

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

Adding some styling to our Lightbox

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("") 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;

JavaScript Lightbox effect

On to our JavaScript, this is the part that will hook everything up and make it work.

What we want to happen:

  • User clicks on an image. We get the src of the image to append it to our Lightbox image and remove the hidden class from our Lightbox
  • User clicks the close button. We re-add the hidden class to our Lightbox.

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, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Did you find this article valuable?

Support Chris Bongers by becoming a sponsor. Any amount is appreciated!

See recent sponsors Learn more about Hashnode Sponsors
Share this