Snippet Saturdays: Image Zoom with Checkboxes
Inline images with fullscreen zoom - no JS required

Snippet Saturdays is something I want to start doing regularly. The purpose is to share small bits of code or whatnot that I found novel or useful. You might already know some of this stuff, but it's new to me, and, well, I just thought it's neat. Probably won't be every Saturday, but we'll see!
So without further ado, let's take a look at the image component I use here in my own blog. Here's an example with a random stock image I pulled off Unsplash. (Photo by Philipp Katzenberger on Unsplash)
The image can be clicked on and it will go fullscreen. Click on the fullscreen image to close it. And there's no JavaScript required, despite what the post tag might imply. 😉
So, without further ado, let's look at the full markup:
<div class="relative">
<!-- Hidden checkbox to toggle fullscreen -->
<input type="checkbox" id="some-unique-id" class="peer hidden" />
<!-- Inline Image -->
<div class="flex flex-col gap-2 text-center">
<label for="some-unique-id" class="cursor-zoom-in">
<img
src={src}
alt={alt}
class="w-full h-auto transition-transform duration-300 rounded-xl hover:scale-[1.02]"
/>
</label>
<span class="description text-sm">image caption here</span>
</div>
<!-- Fullscreen Overlay -->
<div
class="fixed inset-0 z-[999] hidden peer-checked:flex items-center justify-center bg-black bg-opacity-75"
>
<label for="some-unique-id" class="cursor-zoom-out">
<!-- Don't forget alt text! -->
<img src="https://example.com/image.jpg" alt="picture of an XYZ" class="w-full max-h-screen" />
</label>
</div>
</div>
So, let's break down how this works. The main mechanism that allows this to work is the input
tag defined on line 3. This is a checkbox
that conveniently stores a boolean for us.
Next, there are two images. I use Tailwind CSS control everything here, but the logic and CSS itself is really simple.
Essentially, each image is wrapped in a label
component that is tied to the input
via the provided id
(which, I must note, should be unique for each field; Payload, on my backend, has one I can leverage already, but you can use UUIDs, an alphanumeric string of some kind, as long as the ID is unique, of course.)
The label
actually gives us the ability to toggle the input
field's value in a way that's built in to core browser capabilities independent of clientside interactivity such as JavaScript. We actually react to the input's :checked
pseudo element that gets added to the DOM when, well, it's checked.
All you have to do to make it work is make the second image fullscreen. The easiest way is what I did with absolute positioning and cranking up the Z-index. And, of course, it's hidden by default, and reacts using Tailwind's peer-checked
class modifier. However, with vanilla CSS, you might do something like:
#some-unique-id:checked ~ .fullscreen-overlay {
display: flex;
}
And that's it! Feel free to reach out if you have any questions.
Go forth and build great things. 💻 🚀