CSS Advanced
CSS Image Modal
An image modal (or lightbox) enlarges a thumbnail into a centered overlay when clicked. CSS handles the full-screen backdrop, centering, and animation, while a few lines of JavaScript toggle it open and closed.
How a modal works
The modal is a fixed-position overlay that covers the whole viewport with a semi-transparent backdrop. It stays hidden with display: none until a click sets it to display: flex, centering the enlarged content in the middle of the screen.
.modal {
display: none; /* hidden by default */
position: fixed; inset: 0; /* cover viewport */
background: rgba(0,0,0,.8); /* dim backdrop */
align-items: center; justify-content: center;
z-index: 100;
}
.modal.open { display: flex; }Toggling with a little JavaScript
CSS alone cannot respond to an arbitrary click and keep the state, so a tiny script adds and removes an open class. Clicking a thumbnail opens the modal; clicking the backdrop or the close button hides it.
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: sans-serif; padding: 30px; background:#f1f5f9; }
.thumbs { display:flex; gap:16px; }
.thumb {
width:120px; height:120px; border-radius:10px; cursor:pointer;
transition: transform .3s, box-shadow .3s;
}
.thumb:hover { transform: scale(1.05); box-shadow:0 8px 20px rgba(0,0,0,.2); }
.t1 { background:linear-gradient(135deg,#22d3ee,#3b82f6); }
.t2 { background:linear-gradient(135deg,#f472b6,#a855f7); }
.modal {
display:none; position:fixed; inset:0; z-index:100;
background:rgba(0,0,0,.8);
align-items:center; justify-content:center;
animation: fade .3s ease;
}
.modal.open { display:flex; }
@keyframes fade { from { opacity:0; } to { opacity:1; } }
.modal-content {
width:min(80vw,420px); height:min(60vh,320px);
border-radius:14px; box-shadow:0 20px 60px rgba(0,0,0,.5);
}
.close {
position:absolute; top:20px; right:28px;
color:#fff; font-size:40px; cursor:pointer; line-height:1;
}
</style>
</head>
<body>
<p>Click a thumbnail to enlarge it.</p>
<div class="thumbs">
<div class="thumb t1" onclick="openModal('linear-gradient(135deg,#22d3ee,#3b82f6)')"></div>
<div class="thumb t2" onclick="openModal('linear-gradient(135deg,#f472b6,#a855f7)')"></div>
</div>
<div class="modal" id="modal" onclick="closeModal(event)">
<span class="close" onclick="closeModal(event, true)">×</span>
<div class="modal-content" id="modalContent"></div>
</div>
<script>
var modal = document.getElementById("modal");
var content = document.getElementById("modalContent");
function openModal(bg) {
content.style.background = bg;
modal.classList.add("open");
}
function closeModal(e, force) {
if (force || e.target === modal) modal.classList.remove("open");
}
</script>
</body>
</html>Centering and the backdrop
Using display: flex with align-items and justify-content set to center puts the enlarged content in the exact middle regardless of its size. The rgba backdrop dims the page behind it to focus attention.
| Piece | Role |
|---|---|
| position: fixed; inset: 0 | Covers the whole viewport |
| rgba(0,0,0,.8) background | Dim, semi-transparent backdrop |
| display: flex + center | Centers the enlarged image |
| z-index | Stacks the modal above page content |
| .open class | Toggled by JavaScript to show/hide |
Closing the modal
Good modals close in several ways: clicking the X button, clicking the dimmed backdrop outside the image, and (with a bit more script) pressing the Escape key. In the example, the click handler checks whether the backdrop itself was clicked.
Wrap the modal open animation in @keyframes fade so the overlay eases in smoothly rather than appearing instantly.
For real accessibility, move keyboard focus into the modal when it opens, trap focus inside it, and close it on the Escape key. Pure CSS cannot do this alone.
Key points
- The modal is a fixed overlay hidden with display: none by default.
- A small script toggles an open class to show or hide it.
- display: flex with centered alignment centers the enlarged image.
- An rgba backdrop dims the page and can be clicked to close.
- Add Escape-key and focus handling for full accessibility.
