Responsive Modal Image Gallery
Clicking an image in a gallery can open a larger copy of it without taking the visitor away from the page. That larger copy sits in a popup window, a modal, layered above the main content on a semi-transparent background, and a close button or "X" sign in its top-right corner dismisses it.
The example below combines HTML, CSS and JavaScript to build such a gallery, and it is responsive.
CSS builds the modal window and keeps it hidden at first, and JavaScript reveals it with the right image after the user clicks on it.
Example
Prompt
Create a responsive image gallery with four landscape images. When a user clicks an image, a modal overlay appears showing the image larger with a caption and a close button. Use CSS flexbox for the gallery layout with media queries so images show 4 per row on desktop, 2 on tablets, and 1 on mobile. Add a zoom-in animation when the modal opens.
Output: complete HTML page
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Responsive Modal Images</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
h1 {
text-align: center;
padding: 20px;
}
.gallery {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
padding: 0 15px;
}
.gallery-item {
position: relative;
width: calc(25% - 20px);
height: auto;
margin: 10px;
cursor: pointer;
transition: transform 0.5s ease;
}
.gallery-item:hover {
transform: scale(1.1);
}
/* The Modal (background) */
.modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
align-items: center;
justify-content: center;
transition: opacity 0.5s ease;
}
/* Modal content (image) */
.modal-content {
position: relative;
width: 90%;
height: auto;
max-width: 90%;
max-height: 90%;
border-radius: 5px;
overflow: hidden;
animation: zoomIn 0.5s;
}
@keyframes zoomIn {
from { transform: scale(0.6); }
to { transform: scale(1); }
}
.modal.show {
display: flex;
opacity: 1;
}
/* Close button */
.close {
position: absolute;
top: 10px;
right: 15px;
color: #ffffff;
font-size: 35px;
font-weight: bold;
cursor: pointer;
transition: transform 0.3s;
}
/* Caption of modal image */
.caption {
position: absolute;
bottom: 15px;
width: 100%;
text-align: center;
color: #ffffff;
font-size: 24px;
}
@media screen and (max-width: 768px) {
.gallery-item {
width: calc(50% - 20px);
}
}
@media screen and (max-width: 480px) {
.gallery-item {
width: calc(100% - 20px);
}
}
</style>
</head>
<body>
<h1>Responsive Modal Images</h1>
<div class="gallery">
<img src="img_5terre.jpg" alt="Cinque Terre" class="gallery-item" onclick="openModal('modal1', 'Cinque Terre')">
<img src="img_forest.jpg" alt="Forest" class="gallery-item" onclick="openModal('modal2', 'Forest')">
<img src="img_lights.jpg" alt="Northern Lights" class="gallery-item" onclick="openModal('modal3', 'Northern Lights')">
<img src="img_mountains.jpg" alt="Mountains" class="gallery-item" onclick="openModal('modal4', 'Mountains')">
</div>
<div id="modal1" class="modal">
<span class="close" onclick="closeModal('modal1')">×</span>
<img src="img_5terre.jpg" alt="Cinque Terre" class="modal-content">
<div class="caption"></div>
</div>
<div id="modal2" class="modal">
<span class="close" onclick="closeModal('modal2')">×</span>
<img src="img_forest.jpg" alt="Forest" class="modal-content">
<div class="caption"></div>
</div>
<div id="modal3" class="modal">
<span class="close" onclick="closeModal('modal3')">×</span>
<img src="img_lights.jpg" alt="Northern Lights" class="modal-content">
<div class="caption"></div>
</div>
<div id="modal4" class="modal">
<span class="close" onclick="closeModal('modal4')">×</span>
<img src="img_mountains.jpg" alt="Mountains" class="modal-content">
<div class="caption"></div>
</div>
<script>
function openModal(modalId, caption) {
let modal = document.getElementById(modalId);
modal.style.display = "flex";
modal.classList.add("show");
let message = modal.querySelector(".caption");
message.innerText = caption;
}
function closeModal(modalId) {
let modal = document.getElementById(modalId);
modal.classList.remove("show");
setTimeout(function () {
modal.style.display = "none";
modal.querySelector(".caption").innerText = "";
}, 300);
}
</script>
</body>
</html>