Kodza

Image Gallery

An editorial image grid: each image grows into a fullscreen viewer in one continuous motion, with curtain transitions between images and keyboard and swipe support.

Media No dependencies gallerylightboximagetransition Added Jan 2026
/anim/image-gallery/ Fullscreen

With your AI

Just ask.

Say it to your AI. It gets the exact code below, not its best guess, and knows where it goes.

Turn my photos into a Kodza Image Gallery.

Not plugged in yet?
claude mcp add -t http kodza https://kodza.dev/api/mcp
Also in Codex, Cursor and VS Code.
kodza-image-gallery.html
<div class="kodza-gallery" data-kodza-gallery>
  <figure class="kodza-gallery__item" style="--start: 1; --span: 7; --ratio: 3 / 2">
    <button class="kodza-gallery__open" type="button" aria-label="Open image: transition: steps(9)">
      <img class="kodza-gallery__img" src="https://kodza.dev/media/kz-steps-1400.webp" data-full="https://kodza.dev/media/kz-steps-2400.webp" alt="A concrete staircase that climbs nine steps and stops in mid-air" loading="lazy" />
    </button>
    <figcaption class="kodza-gallery__caption">
      <span class="kodza-gallery__index">01</span>
      <span class="kodza-gallery__title">transition: steps(9)</span>
      <span class="kodza-gallery__meta">Leads nowhere</span>
    </figcaption>
  </figure>
  <figure class="kodza-gallery__item" style="--start: 9; --span: 4; --ratio: 4 / 5; --shift: clamp(40px, 8vw, 120px)">
    <button class="kodza-gallery__open" type="button" aria-label="Open image: display: block">
      <img class="kodza-gallery__img" src="https://kodza.dev/media/kz-block-1400.webp" data-full="https://kodza.dev/media/kz-block-2400.webp" alt="A tall concrete slab standing alone, its long shadow stretching toward the viewer" loading="lazy" />
    </button>
    <figcaption class="kodza-gallery__caption">
      <span class="kodza-gallery__index">02</span>
      <span class="kodza-gallery__title">display: block</span>
      <span class="kodza-gallery__meta">Zero dependencies</span>
    </figcaption>
  </figure>
  <figure class="kodza-gallery__item" style="--start: 2; --span: 4; --ratio: 1 / 1">
    <button class="kodza-gallery__open" type="button" aria-label="Open image: border-radius: 50%">
      <img class="kodza-gallery__img" src="https://kodza.dev/media/kz-arch-1400.webp" data-full="https://kodza.dev/media/kz-arch-2400.webp" alt="A concrete wall with a round-topped opening, sunlight pouring through it onto the ground" loading="lazy" />
    </button>
    <figcaption class="kodza-gallery__caption">
      <span class="kodza-gallery__index">03</span>
      <span class="kodza-gallery__title">border-radius: 50%</span>
      <span class="kodza-gallery__meta">Concrete, but soft</span>
    </figcaption>
  </figure>
  <figure class="kodza-gallery__item" style="--start: 7; --span: 5; --ratio: 4 / 3; --shift: clamp(30px, 6vw, 90px)">
    <button class="kodza-gallery__open" type="button" aria-label="Open image: z-index: 9999">
      <img class="kodza-gallery__img" src="https://kodza.dev/media/kz-stack-1400.webp" data-full="https://kodza.dev/media/kz-stack-2400.webp" alt="Three concrete slabs stacked at slightly different angles" loading="lazy" />
    </button>
    <figcaption class="kodza-gallery__caption">
      <span class="kodza-gallery__index">04</span>
      <span class="kodza-gallery__title">z-index: 9999</span>
      <span class="kodza-gallery__meta">Works on my machine</span>
    </figcaption>
  </figure>
  <figure class="kodza-gallery__item" style="--start: 1; --span: 5; --ratio: 4 / 5">
    <button class="kodza-gallery__open" type="button" aria-label="Open image: repeat(7, 1fr)">
      <img class="kodza-gallery__img" src="https://kodza.dev/media/kz-columns-1400.webp" data-full="https://kodza.dev/media/kz-columns-2400.webp" alt="A row of square concrete pillars under a flat roof, casting striped shadows" loading="lazy" />
    </button>
    <figcaption class="kodza-gallery__caption">
      <span class="kodza-gallery__index">05</span>
      <span class="kodza-gallery__title">repeat(7, 1fr)</span>
      <span class="kodza-gallery__meta">Grid, 1968 edition</span>
    </figcaption>
  </figure>
  <figure class="kodza-gallery__item" style="--start: 7; --span: 6; --ratio: 3 / 2; --shift: clamp(40px, 10vw, 150px)">
    <button class="kodza-gallery__open" type="button" aria-label="Open image: position: absolute">
      <img class="kodza-gallery__img" src="https://kodza.dev/media/kz-float-1400.webp" data-full="https://kodza.dev/media/kz-float-2400.webp" alt="A concrete block hovering above the ground, over its own shadow" loading="lazy" />
    </button>
    <figcaption class="kodza-gallery__caption">
      <span class="kodza-gallery__index">06</span>
      <span class="kodza-gallery__title">position: absolute</span>
      <span class="kodza-gallery__meta">Out of the flow</span>
    </figcaption>
  </figure>
</div>

Checked

Checked before you paste.

Robots poked at it before you did. Every component goes through the same checks, and again each time it changes.

What ranLast run
Accessibilityaxe-core 4.10.2: the WCAG 2.1 A and AA rules, plus best practices. 0 issues
KeyboardThe Tab key gets there, and the focus ring shows when it does. Passed
Reduced motionTurn on reduced motion and what moved just appears. Nothing loops. Passed
Light and darkThe same checks on both themes, contrast included. Passed
WordPressPasted into Twenty Twenty-Five, Twenty Twenty-One, Astra, Blocksy, GeneratePress, Hello Elementor, Kadence and OceanWP. Nothing to flag. 8 / 8 themes
Robots checked this. A human with VoiceOver hasn't yet.
KeyboardPress them in the preview
In the viewer
  • Next or previous image, round and round→/←
  • Closes it, the image flies back to its thumbnailEsc

More like this

More in Media