How to build an HTML image gallery

Use the complete gallery below if you want a working page to adapt. It includes the images, responsive layout, captions, and an enlarged view, so you can try the whole result before changing the code.

A row of thumbnails is only the start of a gallery. A reader also needs to know what each image shows, open it without losing their place, and see the same pictures after you send the page.

The example here puts those parts together. It is a small selection of public-domain paintings from The Met, with the image files embedded in the HTML. You can open the downloaded file without depending on a separate pictures folder.

Try an image, move to the next work, and close the enlarged view. At phone width the layout changes without shrinking the captions into tiny text.

A complete painting gallery with captions and a keyboard-operable enlarged view. Open the example to try it.
A complete painting gallery with captions and a keyboard-operable enlarged view. Open the example to try it.
Open the full example ↗

Download the complete HTML. The sample images are included. Replace them with images you have permission to use; preserve the credit information you need for your own collection.

For an exhibition proposal, put the works in viewing order. For a photographer’s shortlist, put the strongest relevant pictures first. The layout is a starting point; the selection should reflect what you want the reader to look at.

The grid should fit its container

The core layout is CSS Grid. This version allows the minimum column width to shrink when the container is narrower than a normal tile:

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: 24px;
}
.gallery figure { margin: 0; min-width: 0; }
.gallery img { display: block; width: 100%; height: auto; }

The columns respond to the available width. In the example, the artwork keeps its natural proportions rather than being cropped into matching squares. That is a deliberate choice for paintings: the whole composition matters.

For product tiles where a repeated shape helps comparison, use an aspect ratio and decide between cover and contain. Cover fills the box by cropping; contain keeps the whole image inside it. Do not crop a label, a face, or the edge of a work by accident.

Keep the picture, label, and description together

Use a figure for a work and a figcaption for the label people can read. The example’s label includes the artist, title, and date.

An image’s alt text serves a different purpose: it provides a text alternative. Describe the relevant visual content, or use an intentional empty value when the image is purely decorative. Alt text explains that decision in more detail.

When replacing a sample work, update the image, its alternative text, its visible label, and the enlarged view together. Otherwise a new photograph can open under the old painting’s title.

An enlarged view needs a way back

The example uses a native dialog, opened with showModal(). A visible close button remains available, Escape dismisses the modal, and closing it returns focus to the image button that opened it. Previous and next controls step through the works.

A few lines of CSS using :target can make a picture larger, but that alone does not implement the same keyboard and focus behavior. If your gallery needs an enlarged view, test those controls rather than stopping when the overlay looks right.

At phone width, make the image fit inside the screen and keep the close button reachable. In this example the navigation buttons are ordinary labeled buttons; swipe navigation is not included.

Make sure the images leave your folder

Choose the asset setup before you send the page:

Setup What needs to travel What to check
An HTML file and image folder The HTML and its folder structure Every relative image path resolves after copying
A page and hosted images The page and accessible image URLs Image permissions and the viewer’s content rules
Images embedded in HTML One larger HTML file The finished file size and image quality

The Met makes designated public-domain works available through Open Access. The sample’s source records are marked public domain; that permission does not automatically apply to images you add.

The download uses the last option. Its images are encoded as data URLs, so there is no request to the museum’s image server when you open the gallery. Self-contained HTML covers the same approach for other kinds of page.

Resize your source images before embedding them. Test the finished file on the device readers will use; counting photos is not a measurement of page weight. A few full-resolution originals can be heavier than a much larger set of resized pictures.

For a one-off handoff, the complete HTML file can be enough. Open that copy from a different folder before sending it. For a selection you expect to revise, a shared page lets readers return to the current version.

In NOS, paste the gallery HTML into a document and check every image and the enlarged view. Use embedded images or the product’s upload route; do not assume outside image URLs work in every publishing environment.

The complete gallery saved in the actual NOS workspace, with the artwork and labels visible together.
The complete gallery saved in the actual NOS workspace, with the artwork and labels visible together.

Open the gallery’s actual share link.

Create the share link and open it as a reader. If someone spots a title typo after you send it, correct the text in the saved page and reopen that same link to verify the change. Replace the image data in the HTML when the artwork itself changes.

Before sharing the finished selection, try it at phone width, tab through the image buttons, open and close the enlarged view, and check that the last image is as complete as the first.

Questions people ask

Can I copy a complete HTML image gallery?

Yes. The example on this page has a downloadable HTML file with its sample images embedded. Save the file, open it in a browser, then replace the sample works, captions, and image data with your own.

Why do the pictures disappear when I share the HTML?

A relative path points to a file beside the HTML, not to an uploaded image. Send the asset folder with the HTML, publish both at matching paths, or embed the images. Check the restrictions of the viewer or publishing tool too.

Does a CSS-only lightbox handle the keyboard?

A CSS target-based view can enlarge an image, but does not automatically provide modal focus management, Escape handling, or focus return. This example uses a native dialog with a close button and adds previous/next controls.

How many photos can I put in one file?

There is no useful universal photo count. The dimensions, encoding, file size, and target device matter. Resize the images and measure the finished file. For large collections, consider hosted assets or separate pages.

Keep reading

Build an HTML lightbox with the dialog elementBuild an image lightbox in plain HTML and JavaScript with the dialog element: captions, nextCSS object-fit: fit any image into a fixed boxHow object-fit fits an image or video into a fixed box: fill, contain, cover, none and scaleCSS filter: every function, liveEvery CSS filter function on one live example: blur, brightness, grayscale, sepia, hue-rotatBuild a carousel in HTML, CSS and JavaScriptBuild an image or card carousel in plain HTML, CSS and JavaScript. Scroll-snap for swipe, a Build a before/after slider with HTML and CSSBuild an accessible before/after image slider, test it on a phone, share it as one live pageImages not showing in an HTML page: the 5 causes and the fix for eachImages not showing in your HTML file? The five causes, how to tell them apart in the NetworkBase64 images in HTML: how and when to embed a pictureA base64 image in HTML is the file's bytes written as text inside the img tag, so the picturAn HTML portfolio template that opens in secondsAn HTML portfolio template that loads fast: image weight, the right formats, lazy-loading beCSS grid: the one line that handles mobile for youCSS grid lays children out in rows and columns you declare. One line, repeat(auto-fit, minmaHow to put an org chart onlinePut an org chart at an address people can open. Build it with nested lists and CSS, keep it How to make an HTML pie chartDraw an HTML pie chart with conic-gradient, SVG, or a chart library. Which to pick, how to lHow to share a catalogue as a linkSend a product catalogue as a link instead of a heavy PDF. It opens on a phone, buyers can s