DEV Community

Cover image for Lightbox, with no JavaScript
Elves Sousa
Elves Sousa

Posted on • Edited on

Lightbox, with no JavaScript

I have been following the evolution of the Web since the 2000s and how things have changed. There are certain things that were only possible to do using JavaScript. Fortunately, today the scenario is different, and we have the luxury of being able to choose whether to use JS or not. One of these things is the effect called "lightbox".

What it is

Lightbox is basically a fancier way to show an enlarged image, without leaving the page to see the entire photo, which is the default behavior of browsers. It usually comes in a frame that opens when clicking on the image, with a close button, to return to the previous view. It was created in 2012 by Lokesh Dakar, and it was a success. Soon followed by competing scripts, using other libraries or having other features. To this day, the Lokesh script works! I left the link to the original Lightbox website at the end of this article.

Nowadays, thanks to advances in CSS, it is possible to achieve the same effect, without the complication of using JavaScript. Below is a tutorial on how to implement one on your website.

The code for the gallery

To achieve the effect, we need an HTML structure to have some example content:

<section class="gallery">
  <h2>Gallery</h2>
  <div class="item">
    <a href="#image1">
      <img src="https://source.unsplash.com/fdlZBWIP0aM/500x500" />
    </a>
    <strong>Photo 1</strong>
  </div>
  <div class="item">
    <a href="#image2">
      <img src="https://source.unsplash.com/Yr4n8O_3UPc/500x500" />
    </a>
    <strong>Photo 3</strong>
  </div>
  <div class="item">
    <a href="#image3">
      <img src="https://source.unsplash.com/_-SwhhV7tSo/500x500" />
    </a>
    <strong>Photo 3</strong>
  </div>
</section>
Enter fullscreen mode Exit fullscreen mode

In the code above, nothing new, just a section with three clickable images. Note that each anchor <a> has an href="#imageN where N is the image number. This will be important later on. The CSS for formatting the content goes below.

@include (https://fonts.googleapis.com/css?family=Montserrat:300,300i,400,400i,700,700i&display=swap);

/* Body */
body {
  background: #111;
  box-sizing: border-box;
  color: #fff;
  font-family: "Montserrat", sans-serif;
  font-size: 12px;
  margin: 0;
  padding: 0;
}

a {
  text-decoration: none;
}

/* gallery */
.gallery {
  display: grid;
  grid-gap: 1em;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 10vh auto;
  margin: 2em auto;
  max-width: 100%;
  width: 600px;
}

.gallery h2 {
  font-size: 30px;
  grid-column: 1/4;
}

.gallery a {
  cursor: zoom-in;
  transition: filter 0.2s ease-in-out;
}

.gallery a:hover {
  filter: brightness(90%);
}

.gallery .item strong {
  display: block;
  font-size: 1.5em;
  text-align: center;
}

.gallery img {
  border-radius: 1em;
  max-width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

I used display: grid in the .gallery section, but this is not part of the effect. I used it just for convenience. In a future article, I will write about how to use Grid Layout.

The code for the lightboxes

HTML is also quite simple. Just create the following structure for each image that you want to have the enlargement effect:

<div class="lightbox" id="imageN">
  <a href="#_" class="close">&times;</a>
  <div class="content">
    <img src="https://source.unsplash.com/fdlZBWIP0aM/900x900" />
    <p>Photo 1</p>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

In this code, we have a <div> with an id equivalent to the href="# imageN" present in the structure made for the gallery; a link with a generic anchor href="#_" to close the window; a <div> for the lightbox content; an 'img' with a higher resolution, to be the enlarged version and an optional caption.

Applying to the three images we have in the gallery, the code will look like this:

<div class="lightboxes">
  <div class="lightbox" id="image1">
    <a href="#" class="close">&times;</a>
    <div class="content">
      <img src="https://source.unsplash.com/fdlZBWIP0aM/900x900" />
      <p>Photo 1</p>
    </div>
  </div>
  <div class="lightbox" id="image2">
    <a href="#" class="close">&times;</a>
    <div class="content">
      <img src="https://source.unsplash.com/Yr4n8O_3UPc/900x900" />
      <p>Photo 2</p>
    </div>
  </div>
  <div class="lightbox" id="image3">
    <a href="#" class="close">&times;</a>
    <div class="content">
      <img src="https://source.unsplash.com/_-SwhhV7tSo/900x900" />
      <p>Photo 3</p>
    </div>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

So far, nothing special. What really changes the game is what comes next.

.lightbox {
  background: rgba(0, 0, 0, 0.8);
  display: none;
  position: fixed;
  z-index: 1000;
}

.lightbox:target {
  align-items: center;
  bottom: 0;
  display: flex;
  justify-content: center;
  left: 0;
  right: 0;
  top: 0;
}

.lightbox img {
  border-radius: 1em;
  display: block;
  margin: auto;
  max-height: 80vh;
  max-width: 90vh;
}

.lightbox .close {
  color: #fff;
  font-size: 4em;
  font-weight: bold;
  height: 1em;
  position: fixed;
  right: 0;
  top: 0;
  width: 1em;
  z-index: 1001;
}

.lightbox p {
  font-size: 2em;
  font-weight: bold;
  text-align: center;
}
Enter fullscreen mode Exit fullscreen mode

Did you notice the pseudo-class :target? It does the trick!

Basically, it makes possible to change the style of the element that has its id at the end of the URL! Quite smart. If the id #image1 is present in the browser address bar, the target will be reached, activating the effect applied in the rule that makes use of this feature.

The only limitation is if you want some extra functionality that is not possible in CSS, such as copying the image to the clipboard, integrating it with some application action or something very specific.

This technique does not need to be used only for this lightbox effect, of course. You can create modals, menus or other effects. Feel free to use your creativity. It is also not limited to enlarging images: any HTML element can be placed in the <div> element displayed after the click.

Use JavaScript only when necessary, otherwise, let CSS give you a little help. It's less logic to worry about.

I left a link below for the CodePen I did showcasing the effect with the code used in this article. Any questions or suggestions, leave a comment!

Links


If this article helped you in some way, consider donating. This will help me to create more content like this!

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.