JSFiddle - React, Tailwind, and code Playground
HTML
<div class="gallery">
<a href="http://placehold.it/450x280/ffcc33"><figure><img src="http://placehold.it/450x280/ffcc33"><figcaption>Test 1</figcaption></figure></a>
<a href="http://placehold.it/450x280/ffcc33"><figure><img src="http://placehold.it/450x280/ffcc33"><figcaption>Test 2</figcaption></figure></a>
<a href="http://placehold.it/450x280/ffcc33"><figure><img src="http://placehold.it/450x280/ffcc33"><figcaption>Test 3</figcaption></figure></a>
<a href="http://placehold.it/450x280/ffcc33"><figure><img src="http://placehold.it/450x280/ffcc33"><figcaption>Test 4</figcaption></figure></a>
<a href="http://placehold.it/450x280/ffcc33"><figure><img src="http://placehold.it/450x280/ffcc33"><figcaption>Test 5</figcaption></figure></a>
<a href="http://placehold.it/450x280/ffcc33"><figure><img src="http://placehold.it/450x280/ffcc33"><figcaption>Test 6</figcaption></figure></a>
<a href="http://placehold.it/450x280/ffcc33"><figure><img src="http://placehold.it/450x280/ffcc33"><figcaption>Test 7</figcaption></figure></a>
<a href="http://placehold.it/450x280/ffcc33"><figure><img src="http://placehold.it/450x280/ffcc33"><figcaption>Test 8</figcaption></figure></a>
<a href="http://placehold.it/450x280/ffcc33"><figure><img src="http://placehold.it/450x280/ffcc33"><figcaption>Test 9</figcaption></figure></a>
</div>
<figure class="pictureView">
<a class="picNav previous"><span>◄</span></a>
<a class="picNav next"><span>►</span></a>
<img src="">
<figcaption>Empty</figcaption>
</figure>
CSS
figure {
min-width: 1px;
max-width: 100%;
min-height: 1px;
margin: 0rem;
}
img {
min-width: 1px;
display: block;
max-width: 100%;
border: 0;
}
.gallery {
display: flex; justify-content: center;
flex-wrap: wrap;
}
.gallery a, .pictureView figure {
position: relative;
margin: 0.5rem;
border-radius: 15px; overflow:hidden;
flex: 0 0 250px;
}
.gallery img {
width: 100%;
}
.gallery figcaption, .pictureView figcaption {
background: rgba(0, 0, 0, 0.5);
color: white;
text-align: center;
position: absolute;
bottom: 0;
width: 100%;
padding: 0.3rem 0rem;
}
.pictureView {
width: 100vw; height: 100vh; position: fixed; top:0; left:0;
display:none;
background-color: rgba(200,200,200,0.9);
user-select:none; /* prevent highlighting on doubleclick */
}
.pictureView.active {
display: flex; justify-content:center; align-items:center;
}
.pictureView .picNav {
position:absolute; display:flex;
flex-direction: column; justify-content:center;
top: 0; width: 25%; height: 100%;
color: transparent;
cursor:pointer;
}
.pictureView .picNav span {
font-size: 10em;
}
.pictureView .picNav:hover {
color: rgba(255,255,255,0.3);
}
.pictureView .picNav.previous {
left:0;
}
.pictureView .picNav.next {
right:0; text-align:right;
}
JavaScript
let gallery = document.querySelector(".gallery");
let viewer = document.querySelector(".pictureView");
gallery.addEventListener("click", handleGalleryClickEvent);
document.body.addEventListener("keydown", handleGlobalKeyEvent);
viewer.addEventListener("click", handleViewerClickEvent);
console.log("foo");
let firstItem = gallery.querySelector("a");
if (firstItem) firstItem.focus();
function handleGalleryClickEvent(event) {
event.preventDefault();
let fig = event.target.closest("a");
if (fig)
activateViewer(fig);
}
function handleGlobalKeyEvent(event) {
if (event.key === "Escape") {
closeViewer();
return;
}
if (viewer.classList.contains("active")) {
if (event.key === "ArrowLeft") navigateViewer("previous");
else if (event.key === "ArrowRight") navigateViewer("next");
}
}
function handleViewerClickEvent(event) {
let navLink = event.target.closest(".picNav");
if (navLink) {
event.preventDefault();
if (navLink.classList.contains("previous")) navigateViewer("previous");
else if (navLink.classList.contains("next")) navigateViewer("next");
}
else if (event.target.closest("figure") === viewer)
closeViewer();
}
function activateViewer(activeItem) {
activeItem.focus();
let galleryItems = gallery.querySelectorAll("a[aria-selected]");
[].forEach.call(galleryItems, function(item) { item.removeAttribute("aria-selected"); });
activeItem.closest("a").setAttribute("aria-selected", true);
viewer.querySelector("img").src = activeItem.querySelector("img").src;
viewer.querySelector("figcaption").textContent = activeItem.querySelector("figcaption").textContent
viewer.classList.add("active");
}
function closeViewer() {
viewer.classList.remove("active");
}
function navigateViewer(direction) {
let currentImage = gallery.querySelector("a[aria-selected]"),
nextImage = null;
if (!currentImage) return;
if (direction === "next") {
nextImage =...