← Back to CSS Course | Chapter 8: Animations & Effects | Lesson 13 of 22

CSS Image Modal

A modal that pops a thumbnail up into a full-screen lightbox is usually thought of as a JavaScript feature, but CSS alone — using either the :target pseudo-class or a hidden checkbox — can open and close one with nothing but link clicks.

The :target Technique

Linking a thumbnail's <a href="#photo1"> to an element with id="photo1" lets CSS style that element differently when it's the page's current URL fragment, using the :target pseudo-class — this is enough to show a hidden full-size overlay purely from a click, no JavaScript required.

Example: The :target Technique

css
<style>
#photo1 {
  display: none;
  background: #333;
  color: white;
  padding: 20px;
}
#photo1:target {
  display: block;
}
</style>
<a href="#photo1">Open photo</a>
<div id="photo1">Full-size image</div>

Building the Modal Overlay

The modal itself is a fixed-position, full-viewport element (position: fixed; inset: 0) that starts hidden with display: none or opacity: 0, and only becomes visible when its :target rule matches, centering the enlarged image with flexbox.

Example: Building the Modal Overlay

css
<style>
.modal {
  display: none;
  position: fixed;
  inset: 0;
}
.modal:target {
  display: flex;
}
</style>
<div id="photo1" class="modal">
  <img src="https://placehold.co/400x300" alt="Enlarged photo">
</div>

Closing the Modal

A close control is just another link, either back to the page's plain # (or no fragment at all) or to a dead anchor — clicking it changes the URL fragment away from the modal's id, so the :target rule no longer matches and the modal disappears.

Example: Closing the Modal

css
<style>
.modal {
  display: none;
  background: rgba(0,0,0,0.7);
  color: white;
  padding: 20px;
}
.modal:target {
  display: block;
}
</style>
<div id="photo1" class="modal">
  <a href="#" style="color: white;">Close</a>
</div>

The Checkbox Hack Alternative

An alternative technique hides a real <input type="checkbox"> off-screen and pairs it with a <label> that toggles it; CSS then uses the :checked pseudo-class on a sibling selector to show or hide the modal based on the checkbox's state instead of the URL.

Example: The Checkbox Hack Alternative

css
<style>
.modal {
  display: none;
  background: #333;
  color: white;
  padding: 20px;
}
#toggle:checked ~ .modal {
  display: block;
}
</style>
<input type="checkbox" id="toggle" hidden>
<label for="toggle">Open</label>
<div class="modal">Shown via :checked, no URL change</div>

:target vs Checkbox Hack

The :target approach changes the actual URL (useful for direct-linking to a specific opened image, but means the back button also closes it), while the checkbox hack leaves the URL untouched but requires careful sibling-selector structuring since :checked can only affect elements that come after the checkbox in the DOM.

Example: :target vs Checkbox Hack

css
<style>
#a:target { background: yellow; }
</style>
<a href="#a">Target link changes the URL, back button closes it</a>
<div id="a">Target section</div>

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.