Building a leaner image gallery with platform features
Image galleries are one of the most common page patterns on the web, but they can also be among the heaviest. Every thumbnail adds download weight, and the JavaScript libraries often pulled in for lightbox behavior and lazy scrolling inflate page size even further. Much of what those libraries do has since landed natively in browsers, so it’s worth examining what a gallery built entirely from Baseline features looks like.
Reducing the image payload
Large images are a performance problem, and galleries multiply that problem. Two Baseline features in particular help keep the download size in check without sacrificing image quality.
Defer off-screen images with native lazy loading
Images that aren’t visible when the page first paints shouldn’t all be fetched at once. The standard approach has been to use an IntersectionObserver or pull in a library, but both add code and potential failure points. The platform now handles this with a simple HTML attribute.
Adding loading="lazy" to an <img> element tells the browser to postpone the request until the image is near the viewport. For thumbnails that are certain to be visible at load time, you can explicitly set loading="eager" on the first few — or just omit the attribute, since eager is the default.
Lazy loading also applies to images that are initially hidden in other ways, such as inside a closed <dialog>. That means the same mechanism can handle fetching larger versions of an image only after a user clicks to view it.
One important companion detail: always specify your image dimensions. In the demo, the grid itself defines the inline size, and the gallery items set aspect-ratio: 1 / 1 so the block size matches. This reserves space before the image arrives, preventing layout shift. Setting explicit width and height attributes on the image tag works as well.
Swap JPEGs and PNGs for AVIF
The gallery of thumbnails needs suitably compressed files, not full-resolution originals. The AVIF format offers a strong alternative to legacy formats like JPEG and PNG. It supports transparency, animation, and HDR imagery, while frequently producing considerably smaller file sizes than other formats.
The demo images were converted from JPG to AVIF, yielding drastically reduced sizes while maintaining acceptable visual quality. For experimenting, tools like Squoosh and Cloudinary handle one-off conversions, while newer versions of Photoshop and GIMP include AVIF export options. ImageMagick enables integrating AVIF encoding into automated processing pipelines.
Implementing a lightbox without hacks
Launching into a larger view of an image used to involve positioning elements with z-index and manual focus management. HTML's <dialog> element solves much of that problem by design.
A dialog places its content into the top layer, separate from the normal document flow. You can create the dimming effect behind the lightbox with the ::backdrop pseudo-element, which sits between the dialog and the rest of the page. Because this all operates outside the document stacking context, z-index becomes a non-issue for this part of the gallery.
The <dialog> element also improves accessibility by handling focus management with less custom JavaScript than typical homegrown lightbox code. When the dialog closes, focus returns to the element that opened it.
Smoothing the transition
Dialogs appear and disappear instantly by default. To give the lightbox a subtle open and close transition, the demo uses the allow-discrete transition behavior and the @starting-style at-rule to define a starting CSS state for the dialog's appearance.
Styling and other refinements
Improving text legibility over images
Overlaying text on a button that sits above an image is a classic readability problem. Rather than relying on a semi-transparent background that may not provide enough contrast across all images, the backdrop-filter property styles the area behind the element directly.
Used with pseudo-classes such as :hover and :focus, you can apply a blur or color filter to what's underneath the button, ensuring the text stays legible regardless of the image beneath it.
Accessing finer detail on hires screens
On standard displays a 1px top border is sufficient, but high-resolution screens can render a subpixel line for a slightly crisper edge. A resolution media query in the demo offers that refinement, letting those displays declare a thinner border while preserving the default for everyone else.
Keeping grid tiles uniform
Displaying images at consistent dimensions requires defining their geometry before content arrives. The CSS aspect-ratio property nails this — in the demo, the ratio is 1 / 1, meaning the height is always equal to the width. The width is derived from the grid-template-columns definition, which carries a minimum of 16em per column and lets the layout expand until a new column can fit.
Paired with object-fit: cover, the displayed image fills its container on both axes, cropping any part of it that would overflow.
Building on the base pattern
Two additional Baseline features can extend the gallery further. If you add previous/next navigation inside the dialog lightbox, CSS view transitions can animate the switch between images. Where you can generate image variants at different resolutions, the <picture> element allows serving the optimal file size for each viewpoint length.
These platform features make a functional, performant gallery less dependent on extra code assets — the native building blocks can either form the full implementation or drop into an existing setup.



