Open the full-page example → · Download complete recipe (ZIP)
Try the working example
The preview runs only our supplied example code. Entries stay in the page; the practice form cannot send them. For keyboard testing, use the full-page example.
Build it step by step
- Start with a figure for each image and its caption. The content works before layout is added.
- Supply width and height matching the image. This lets the browser reserve its aspect ratio.
- Use auto-fit to create as many columns as fit. The nested min() prevents the minimum column size from overflowing a narrow container.
- Resize the window and zoom the text. Read the alt text separately from the caption: each has a different job.
Why it works
Grid arranges the cards; the image remains proportional inside each card. These examples use vector artwork, so they do not need different-resolution files. Photographs usually benefit from appropriately sized raster sources.
A mistake worth catching
A fixed 240px minimum can overflow a container narrower than 240px. Stretching an image with an unrelated fixed height can also distort it.
Read the complete source
The ZIP also includes the local font and its licence, a README and any illustrations. The source below is the same code used in the preview.
HTML source
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="Mario V.W.B.R. Obst"><meta name="robots" content="noindex, follow"><meta name="referrer" content="no-referrer">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self'; font-src 'self'; connect-src 'none'; form-action 'none'; object-src 'none'; base-uri 'none'">
<title>A gallery that finds its own columns</title><link rel="stylesheet" href="style.css">
</head>
<body><main><h1>Small landscapes, large possibilities.</h1><p>Three original geometric illustrations. Resize the window and watch the columns adapt.</p><div class="gallery"><figure><img src="landscape-1.svg" width="640" height="400" alt="An orange sun above overlapping blue hills"><figcaption>01 · A slow morning</figcaption></figure><figure><img src="landscape-2.svg" width="640" height="400" alt="An orange sun above overlapping teal hills"><figcaption>02 · The long way home</figcaption></figure><figure><img src="landscape-3.svg" width="640" height="400" alt="An orange sun above overlapping violet hills"><figcaption>03 · After the last train</figcaption></figure></div></main></body></html>CSS source
@font-face{font-family:FYI;src:url("inter.ttf") format("truetype");font-weight:100 900;font-display:swap}
*{box-sizing:border-box}html{color-scheme:dark}body{margin:0;background:#20212a;color:#efedf6;font-family:FYI,sans-serif;line-height:1.6}main{max-width:960px;margin:auto;padding:24px}h1,h2{line-height:1.15}a{color:#ff9b45}button,input,select,textarea{font:inherit;color:inherit;background:#282934;border:1px solid #777582;border-radius:6px;padding:10px}button{cursor:pointer}button:disabled{cursor:default;opacity:.5}:focus-visible{outline:3px solid #ff9b45;outline-offset:4px}label{display:block;margin-top:16px}button{margin:12px 8px 12px 0}p{max-width:70ch}.hint{color:#c7c3d2} [hidden]{display:none!important}.panel{padding:20px;border:1px solid #555361;border-radius:12px;background:#282934}img{max-width:100%;height:auto}code{overflow-wrap:anywhere}input,select,textarea{max-width:100%}a,button{touch-action:manipulation}
.gallery{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:20px}figure{margin:0;background:#282934;border-radius:12px;overflow:hidden}figure img{display:block;width:100%}figcaption{padding:16px}landscape-1.svg
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="400" viewBox="0 0 640 400"><rect width="640" height="400" fill="#20212a"/><circle cx="210" cy="120" r="52" fill="#ff7700"/><path d="M0 290 Q160 90 330 270 T640 200 V400 H0Z" fill="#526b8c"/><path d="M0 330 Q220 190 380 320 T640 260 V400 H0Z" fill="#304b6c"/></svg>landscape-2.svg
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="400" viewBox="0 0 640 400"><rect width="640" height="400" fill="#20212a"/><circle cx="290" cy="120" r="52" fill="#ff7700"/><path d="M0 290 Q160 90 330 270 T640 200 V400 H0Z" fill="#3b817b"/><path d="M0 330 Q220 190 380 320 T640 260 V400 H0Z" fill="#235a58"/></svg>landscape-3.svg
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="400" viewBox="0 0 640 400"><rect width="640" height="400" fill="#20212a"/><circle cx="370" cy="120" r="52" fill="#ff7700"/><path d="M0 290 Q160 90 330 270 T640 200 V400 H0Z" fill="#736589"/><path d="M0 330 Q220 190 380 320 T640 260 V400 H0Z" fill="#514361"/></svg>Take it one step further
Add a fourth original illustration. Then try a wider gallery without changing any breakpoint. Explain why the number of columns changes.
Check your work
Try a narrow window, 200% zoom and keyboard-only operation. Disable JavaScript to inspect the fallback. For motion, test your reduced-motion preference. Do not use real personal details in learning forms.
Keep exploring
Read the companion guide · Practise finding small mistakes · All code recipes
Technical reference and authorship
Read the underlying platform documentation (new tab). The explanation, composition and example were written for this site; this link is a factual reference, not a source of a copied template. Inter has its own font licence in the download.
Use and adapt the original example for your own learning. For other reuse, see Legal information. About AI assistance.