Snippet Saturdays: Image Zoom with Checkboxes

Inline images with fullscreen zoom - no JS required

2 min read
#web development
by
protocol7 avatar
protocol7

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:

html code
<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:

css code
#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. 💻 🚀