Author: | jrrio |
---|---|
Views Total: | 1,438 views |
Official Page: | Go to website |
Last Update: | October 9, 2020 |
License: | MIT |
Preview:

Description:
A fully responsive photo gallery that allows the user to open the images in a fullscreen lightbox with image descriptions and links.
Built with CSS, CSS Grid Layout, and Vanilla JavaScript.
How to use it:
1. Add images together with links (using data-url
attribute as shown below) and descriptions to the photo gallery.
<section class="gallery"> <div class="container"> <h1 class="gallery-heading">MY Photo Gallery</h1> <div class="gallery-grid"> <div class="gallery-item"> <img src="1.jpg" alt="Image 1"> <div class="gallery-item-text" data-url="https://cssscript.com"> Image Description 1 </div> </div> <div class="gallery-item"> <img src="2.jpg" alt="Image 2"> <div class="gallery-item-text" data-url="https://cssscript.com"> Image Description 2 </div> </div> <div class="gallery-item"> <img src="2.jpg" alt="Image 2"> <div class="gallery-item-text" data-url="https://cssscript.com"> Image Description 3 </div> </div> ... </div> </div> </section>
2. The necessary CSS styles for the photo gallery.
img { border: 0; display: block; /* collapse top and bottom margins */ max-width: 100%; } .container { margin: 0 auto; max-width: 560px; } .gallery { padding-bottom: 10px; text-align: center; } .gallery-heading { color: #00d6c8; font-weight: 600; letter-spacing: 0.1em; line-height: 1.15; text-transform: uppercase; margin-top: 0; position: relative; padding-bottom: 8px; } .gallery-heading::after { content: ""; background-color: currentColor; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); height: 1px; width: 100px; } .gallery-grid { background: #283048; background: linear-gradient(to right, #355460, #283048); display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); grid-auto-rows: minmax(200px, -webkit-max-content); grid-auto-rows: minmax(200px, max-content); grid-auto-flow: dense; gap: 10px; margin-top: 40px; padding: 10px; } .gallery-item img { cursor: pointer; -o-object-fit: cover; object-fit: cover; width: 100%; height: 100%; } .gallery-item-text { display: none; }
3. Create the HTML for the image lightbox.
<div class="lightbox preload"> <div class="lb-content"> <!-- You may put a loader gif or svg here for starters --> <img class="lb-img" src="/img/loader.svg" alt="lightbox image"> <div class="lb-caption"> <a class="lb-url" href="" rel="noopener" target="_blank">Link to Site →</a> <div class="lb-text"></div> </div> <a href="#" class="close">×</a> </div> </div>
4. The necessary CSS styles for the image lightbox.
.lightbox { display: flex; align-items: center; justify-content: center; position: fixed; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; pointer-events: none; transition: opacity 0.5s; z-index: 10; } /* .preload will be removed by JS code during DOMContentLoaded event. This is done to avoid lightbox transition appearing on page load. */ .lightbox.preload { transition: none !important; } .lightbox.open { opacity: 1; pointer-events: auto; } .lightbox .lb-content { background-color: lightgray; display: flex; flex-direction: column; justify-content: center; margin: 1em; max-height: 90%; padding: 1rem; position: relative; } .lightbox .lb-img { -o-object-fit: contain; object-fit: contain; margin-bottom: 8px; display: block; width: 100%; height: auto; } .lightbox .lb-caption { color: #333; display: flex; flex-direction: column; font-size: 0.9rem; max-width: 50ch; overflow-y: auto; /* may occur in smartphones */ opacity: 0; transition: opacity 0.3s; } .lightbox.open .lb-caption { opacity: 1; } .lightbox .lb-url { color: #005fa9; text-decoration: underline; text-underline-position: under; padding-top: 8px; padding-bottom: 14px; } .lightbox .close { background-color: lightgray; cursor: pointer; color: #333; text-decoration: none; display: inline-block; font-size: 2em; line-height: 1em; text-align: center; position: absolute; top: -0.4em; right: -0.4em; width: 1em; height: 1em; border-radius: 50%; } /* Lightbox overlay */ .lightbox .close::before { background-color: rgba(0, 0, 0, 0.9); content: ""; cursor: default; position: fixed; left: 0; top: 0; width: 100%; height: 100%; z-index: -1; }
5. Make the photo gallery & image lightbox full responsive.
/* Medium devices (landscape tablets, 768px and up) */ @media screen and (min-width: 768px) { .container { max-width: 720px; } .lightbox .lb-caption { font-size: 1rem; } } /* Large devices (laptops/desktops, 1024px and up) */ @media screen and (min-width: 1024px) { .container { max-width: 960px; } .lightbox .lb-content { flex-direction: row; } .lightbox .lb-img { margin-bottom: 0; } .lightbox .lb-caption { padding: 0 1.5em; } .lightbox .lb-url { padding-top: 0; } }
6. The core JavaScript to enable the image lightbox.
// Helper functions let qs = (selector, context = document) => context.querySelector(selector); let qsa = (selector, context = document) => Array.from(context.querySelectorAll(selector)); // Get gallery item into Lightbox function openLightbox(e) { const gitem = e.currentTarget, itemimg = qs("img", gitem), itemtext = qs(".gallery-item-text", gitem), itemUrl = itemtext.dataset.url; // Fill in the elements of lightbox. const lightbox = qs(".lightbox"), lightboximg = qs(".lb-img", lightbox), lightboxtext = qs(".lb-text", lightbox), lightboxDataURL = qs(".lb-url", lightbox); lightboximg.onload = () => { // fires as soon as image.src is assigned a URL. lightboxtext.innerHTML = itemtext.innerHTML; lightboxDataURL.setAttribute("href", itemUrl); lightbox.classList.add("open"); }; // Assigns a relative url. This will fire onload. lightboximg.setAttribute("src", itemimg.getAttribute("src")); } function closeLightbox(e) { e.preventDefault(); const lightbox = e.currentTarget.closest(".lightbox"); lightbox.classList.remove("open"); } document.addEventListener("DOMContentLoaded", () => { const lightbox = qs(".lightbox.preload"); if (lightbox) lightbox.classList.remove("preload"); const gitems = qsa(".gallery-item"); gitems.forEach((el) => el.addEventListener("click", openLightbox)); const lbclose = qs(".lightbox .close"); if (lbclose) lbclose.addEventListener("click", closeLightbox); });
Changelog:
10/09/2020
- JS & CSS updated