By Mario V.W.B.R. Obst · Original learning example · September 2026

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

  1. Start with a figure for each image and its caption. The content works before layout is added.
  2. Supply width and height matching the image. This lets the browser reserve its aspect ratio.
  3. Use auto-fit to create as many columns as fit. The nested min() prevents the minimum column size from overflowing a narrow container.
  4. 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
HTML · EXAMPLE
<!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
CSS · EXAMPLE
@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 · EXAMPLE
<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 · EXAMPLE
<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 · EXAMPLE
<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.