Snippets Animation

Bootstrap 5 Card Gallery with View Transitions

A filterable photo card gallery where cards glide into their new positions and a chosen photo morphs into a full detail view, powered by the View Transitions API. It falls back to instant updates when the API is unsupported or reduced motion is preferred, and works fully from the keyboard.

Bootstrap 5 No jQuery Oct 2026

<section class="wdw-stage vt-gallery">
  <div class="container" style="max-width:1040px">
    <div class="vt-view-grid">
      <div class="d-flex flex-column flex-md-row align-items-md-end justify-content-between gap-3 mb-4">
        <div>
          <span class="wdw-eyebrow">Field notes</span>
          <h2 class="wdw-heading display-6 mb-1">Wild places</h2>
          <p class="wdw-muted mb-0" id="vt-count" role="status" aria-live="polite">Showing 9 of 9 photos</p>
        </div>
        <div class="d-flex flex-wrap gap-2" role="group" aria-label="Filter photos by category">
        <button type="button" class="btn rounded-pill btn-primary px-4" data-filter="all" aria-pressed="true">All</button>
        <button type="button" class="btn rounded-pill btn-outline-primary px-4" data-filter="mountains" aria-pressed="false">Mountains</button>
        <button type="button" class="btn rounded-pill btn-outline-primary px-4" data-filter="water" aria-pressed="false">Water</button>
        <button type="button" class="btn rounded-pill btn-outline-primary px-4" data-filter="wild" aria-pressed="false">Wilderness</button>
        </div>
      </div>
      <ul class="list-unstyled row row-cols-1 row-cols-sm-2 row-cols-lg-3 g-3 g-lg-4 mb-0" id="vt-grid">
      <li class="col" data-id="0" data-category="mountains">
        <article class="wdw-card-sm vt-card h-100 position-relative overflow-hidden">
          <img class="vt-photo w-100" src="https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?w=640&h=480&fit=crop&auto=format&q=70" width="640" height="480" alt="Pine ridge: evergreens climb a ridge while snow holds on to the far peaks">
          <div class="p-3 d-flex align-items-center justify-content-between gap-2">
            <h3 class="h6 fw-bold mb-0"><button type="button" class="btn btn-link stretched-link p-0 text-body-emphasis text-decoration-none vt-open" style="min-height:0">Pine ridge</button></h3>
            <span class="badge rounded-pill text-bg-light border">Mountains</span>
          </div>
        </article>
      </li>
      <li class="col" data-id="1" data-category="water">
        <article class="wdw-card-sm vt-card h-100 position-relative overflow-hidden">
          <img class="vt-photo w-100" src="https://images.unsplash.com/photo-1501785888041-af3ef285b470?w=640&h=480&fit=crop&auto=format&q=70" width="640" height="480" alt="Alpine lake: glacier-green water, a single rowing boat and cliffs on both sides">
          <div class="p-3 d-flex align-items-center justify-content-between gap-2">
            <h3 class="h6 fw-bold mb-0"><button type="button" class="btn btn-link stretched-link p-0 text-body-emphasis text-decoration-none vt-open" style="min-height:0">Alpine lake</button></h3>
            <span class="badge rounded-pill text-bg-light border">Water</span>
          </div>
        </article>
      </li>
      <li class="col" data-id="2" data-category="wild">
        <article class="wdw-card-sm vt-card h-100 position-relative overflow-hidden">
          <img class="vt-photo w-100" src="https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=640&h=480&fit=crop&auto=format&q=70" width="640" height="480" alt="Forest trail: tall trunks, low sun and a path that disappears around the bend">
          <div class="p-3 d-flex align-items-center justify-content-between gap-2">
            <h3 class="h6 fw-bold mb-0"><button type="button" class="btn btn-link stretched-link p-0 text-body-emphasis text-decoration-none vt-open" style="min-height:0">Forest trail</button></h3>
            <span class="badge rounded-pill text-bg-light border">Wilderness</span>
          </div>
        </article>
      </li>
      <li class="col" data-id="3" data-category="mountains">
        <article class="wdw-card-sm vt-card h-100 position-relative overflow-hidden">
          <img class="vt-photo w-100" src="https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=640&h=480&fit=crop&auto=format&q=70" width="640" height="480" alt="Golden ridge: haze softens the layers of a valley while a lone hiker stands on the rocks above it">
          <div class="p-3 d-flex align-items-center justify-content-between gap-2">
            <h3 class="h6 fw-bold mb-0"><button type="button" class="btn btn-link stretched-link p-0 text-body-emphasis text-decoration-none vt-open" style="min-height:0">Golden ridge</button></h3>
            <span class="badge rounded-pill text-bg-light border">Mountains</span>
          </div>
        </article>
      </li>
      <li class="col" data-id="4" data-category="water">
        <article class="wdw-card-sm vt-card h-100 position-relative overflow-hidden">
          <img class="vt-photo w-100" src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?w=640&h=480&fit=crop&auto=format&q=70" width="640" height="480" alt="River at dawn: a shallow river carries the first pink light between dark pines">
          <div class="p-3 d-flex align-items-center justify-content-between gap-2">
            <h3 class="h6 fw-bold mb-0"><button type="button" class="btn btn-link stretched-link p-0 text-body-emphasis text-decoration-none vt-open" style="min-height:0">River at dawn</button></h3>
            <span class="badge rounded-pill text-bg-light border">Water</span>
          </div>
        </article>
      </li>
      <li class="col" data-id="5" data-category="wild">
        <article class="wdw-card-sm vt-card h-100 position-relative overflow-hidden">
          <img class="vt-photo w-100" src="https://images.unsplash.com/photo-1519681393784-d120267933ba?w=640&h=480&fit=crop&auto=format&q=70" width="640" height="480" alt="Milky Way peaks: snowy summits under a dense band of stars">
          <div class="p-3 d-flex align-items-center justify-content-between gap-2">
            <h3 class="h6 fw-bold mb-0"><button type="button" class="btn btn-link stretched-link p-0 text-body-emphasis text-decoration-none vt-open" style="min-height:0">Milky Way peaks</button></h3>
            <span class="badge rounded-pill text-bg-light border">Wilderness</span>
          </div>
        </article>
      </li>
      <li class="col" data-id="6" data-category="mountains">
        <article class="wdw-card-sm vt-card h-100 position-relative overflow-hidden">
          <img class="vt-photo w-100" src="https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05?w=640&h=480&fit=crop&auto=format&q=70" width="640" height="480" alt="Valley mist: cloud spills over a green escarpment as the sun breaks through">
          <div class="p-3 d-flex align-items-center justify-content-between gap-2">
            <h3 class="h6 fw-bold mb-0"><button type="button" class="btn btn-link stretched-link p-0 text-body-emphasis text-decoration-none vt-open" style="min-height:0">Valley mist</button></h3>
            <span class="badge rounded-pill text-bg-light border">Mountains</span>
          </div>
        </article>
      </li>
      <li class="col" data-id="7" data-category="water">
        <article class="wdw-card-sm vt-card h-100 position-relative overflow-hidden">
          <img class="vt-photo w-100" src="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?w=640&h=480&fit=crop&auto=format&q=70" width="640" height="480" alt="Sunset shore: warm light on the foam and a long, flat beach">
          <div class="p-3 d-flex align-items-center justify-content-between gap-2">
            <h3 class="h6 fw-bold mb-0"><button type="button" class="btn btn-link stretched-link p-0 text-body-emphasis text-decoration-none vt-open" style="min-height:0">Sunset shore</button></h3>
            <span class="badge rounded-pill text-bg-light border">Water</span>
          </div>
        </article>
      </li>
      <li class="col" data-id="8" data-category="wild">
        <article class="wdw-card-sm vt-card h-100 position-relative overflow-hidden">
          <img class="vt-photo w-100" src="https://images.unsplash.com/photo-1469975692758-66d107a536cb?w=640&h=480&fit=crop&auto=format&q=70" width="640" height="480" alt="Desert stars: sandstone towers glow against a night sky">
          <div class="p-3 d-flex align-items-center justify-content-between gap-2">
            <h3 class="h6 fw-bold mb-0"><button type="button" class="btn btn-link stretched-link p-0 text-body-emphasis text-decoration-none vt-open" style="min-height:0">Desert stars</button></h3>
            <span class="badge rounded-pill text-bg-light border">Wilderness</span>
          </div>
        </article>
      </li>
      </ul>
    </div>

    <div class="vt-view-detail wdw-card p-3 p-lg-4" hidden>
      <div class="d-flex align-items-center justify-content-between gap-2 mb-3">
        <button type="button" class="btn btn-outline-primary rounded-pill px-3 vt-back"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6"/></svg> Back to gallery</button>
        <div class="d-flex gap-2">
          <button type="button" class="btn btn-outline-secondary rounded-pill px-3 vt-step" data-dir="-1" aria-label="Previous photo"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6"/></svg></button>
          <button type="button" class="btn btn-outline-secondary rounded-pill px-3 vt-step" data-dir="1" aria-label="Next photo"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 18l6-6-6-6"/></svg></button>
        </div>
      </div>
      <div class="vt-detail-body">
        <div class="vt-detail-item row g-4 g-lg-5 align-items-center" data-detail="0" hidden>
          <div class="col-lg-7"><img class="vt-photo w-100" src="https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?w=1200&h=900&fit=crop&auto=format&q=70" width="1200" height="900" loading="lazy" alt="Pine ridge: evergreens climb a ridge while snow holds on to the far peaks"></div>
          <div class="col-lg-5">
            <span class="badge rounded-pill bg-primary-subtle text-primary-emphasis mb-3">Mountains</span>
            <h2 class="wdw-heading h2 mb-3" tabindex="-1">Pine ridge</h2>
            <p class="wdw-muted mb-4">Evergreens climb a ridge while snow holds on to the far peaks. A wide, clear view that rewards the early start.</p>
            <dl class="row g-0 small mb-4">
              <dt class="col-5 wdw-muted fw-medium">Best light</dt><dd class="col-7 fw-semibold mb-2">Late morning</dd>
              <dt class="col-5 wdw-muted fw-medium">Mood</dt><dd class="col-7 fw-semibold mb-0">Clear and crisp</dd>
            </dl>
          </div>
        </div>
        <div class="vt-detail-item row g-4 g-lg-5 align-items-center" data-detail="1" hidden>
          <div class="col-lg-7"><img class="vt-photo w-100" src="https://images.unsplash.com/photo-1501785888041-af3ef285b470?w=1200&h=900&fit=crop&auto=format&q=70" width="1200" height="900" loading="lazy" alt="Alpine lake: glacier-green water, a single rowing boat and cliffs on both sides"></div>
          <div class="col-lg-5">
            <span class="badge rounded-pill bg-primary-subtle text-primary-emphasis mb-3">Water</span>
            <h2 class="wdw-heading h2 mb-3" tabindex="-1">Alpine lake</h2>
            <p class="wdw-muted mb-4">Glacier-green water, a single rowing boat and cliffs on both sides. The kind of still you only get before the wind picks up.</p>
            <dl class="row g-0 small mb-4">
              <dt class="col-5 wdw-muted fw-medium">Best light</dt><dd class="col-7 fw-semibold mb-2">Early morning</dd>
              <dt class="col-5 wdw-muted fw-medium">Mood</dt><dd class="col-7 fw-semibold mb-0">Calm and bright</dd>
            </dl>
          </div>
        </div>
        <div class="vt-detail-item row g-4 g-lg-5 align-items-center" data-detail="2" hidden>
          <div class="col-lg-7"><img class="vt-photo w-100" src="https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=1200&h=900&fit=crop&auto=format&q=70" width="1200" height="900" loading="lazy" alt="Forest trail: tall trunks, low sun and a path that disappears around the bend"></div>
          <div class="col-lg-5">
            <span class="badge rounded-pill bg-primary-subtle text-primary-emphasis mb-3">Wilderness</span>
            <h2 class="wdw-heading h2 mb-3" tabindex="-1">Forest trail</h2>
            <p class="wdw-muted mb-4">Tall trunks, low sun and a path that disappears around the bend. Slow down; the light changes every few steps.</p>
            <dl class="row g-0 small mb-4">
              <dt class="col-5 wdw-muted fw-medium">Best light</dt><dd class="col-7 fw-semibold mb-2">Golden hour</dd>
              <dt class="col-5 wdw-muted fw-medium">Mood</dt><dd class="col-7 fw-semibold mb-0">Hushed and warm</dd>
            </dl>
          </div>
        </div>
        <div class="vt-detail-item row g-4 g-lg-5 align-items-center" data-detail="3" hidden>
          <div class="col-lg-7"><img class="vt-photo w-100" src="https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=1200&h=900&fit=crop&auto=format&q=70" width="1200" height="900" loading="lazy" alt="Golden ridge: haze softens the layers of a valley while a lone hiker stands on the rocks above it"></div>
          <div class="col-lg-5">
            <span class="badge rounded-pill bg-primary-subtle text-primary-emphasis mb-3">Mountains</span>
            <h2 class="wdw-heading h2 mb-3" tabindex="-1">Golden ridge</h2>
            <p class="wdw-muted mb-4">Haze softens the layers of a valley while a lone hiker stands on the rocks above it. Plan extra time for the descent.</p>
            <dl class="row g-0 small mb-4">
              <dt class="col-5 wdw-muted fw-medium">Best light</dt><dd class="col-7 fw-semibold mb-2">Sunrise</dd>
              <dt class="col-5 wdw-muted fw-medium">Mood</dt><dd class="col-7 fw-semibold mb-0">Hazy and gold</dd>
            </dl>
          </div>
        </div>
        <div class="vt-detail-item row g-4 g-lg-5 align-items-center" data-detail="4" hidden>
          <div class="col-lg-7"><img class="vt-photo w-100" src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?w=1200&h=900&fit=crop&auto=format&q=70" width="1200" height="900" loading="lazy" alt="River at dawn: a shallow river carries the first pink light between dark pines"></div>
          <div class="col-lg-5">
            <span class="badge rounded-pill bg-primary-subtle text-primary-emphasis mb-3">Water</span>
            <h2 class="wdw-heading h2 mb-3" tabindex="-1">River at dawn</h2>
            <p class="wdw-muted mb-4">A shallow river carries the first pink light between dark pines. Wet rocks make the best foreground.</p>
            <dl class="row g-0 small mb-4">
              <dt class="col-5 wdw-muted fw-medium">Best light</dt><dd class="col-7 fw-semibold mb-2">Dawn</dd>
              <dt class="col-5 wdw-muted fw-medium">Mood</dt><dd class="col-7 fw-semibold mb-0">Cool and quiet</dd>
            </dl>
          </div>
        </div>
        <div class="vt-detail-item row g-4 g-lg-5 align-items-center" data-detail="5" hidden>
          <div class="col-lg-7"><img class="vt-photo w-100" src="https://images.unsplash.com/photo-1519681393784-d120267933ba?w=1200&h=900&fit=crop&auto=format&q=70" width="1200" height="900" loading="lazy" alt="Milky Way peaks: snowy summits under a dense band of stars"></div>
          <div class="col-lg-5">
            <span class="badge rounded-pill bg-primary-subtle text-primary-emphasis mb-3">Wilderness</span>
            <h2 class="wdw-heading h2 mb-3" tabindex="-1">Milky Way peaks</h2>
            <p class="wdw-muted mb-4">Snowy summits under a dense band of stars. Far from town lights the sky does most of the work for you.</p>
            <dl class="row g-0 small mb-4">
              <dt class="col-5 wdw-muted fw-medium">Best light</dt><dd class="col-7 fw-semibold mb-2">New moon</dd>
              <dt class="col-5 wdw-muted fw-medium">Mood</dt><dd class="col-7 fw-semibold mb-0">Silent and vast</dd>
            </dl>
          </div>
        </div>
        <div class="vt-detail-item row g-4 g-lg-5 align-items-center" data-detail="6" hidden>
          <div class="col-lg-7"><img class="vt-photo w-100" src="https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05?w=1200&h=900&fit=crop&auto=format&q=70" width="1200" height="900" loading="lazy" alt="Valley mist: cloud spills over a green escarpment as the sun breaks through"></div>
          <div class="col-lg-5">
            <span class="badge rounded-pill bg-primary-subtle text-primary-emphasis mb-3">Mountains</span>
            <h2 class="wdw-heading h2 mb-3" tabindex="-1">Valley mist</h2>
            <p class="wdw-muted mb-4">Cloud spills over a green escarpment as the sun breaks through. A narrow road is the only sign of people.</p>
            <dl class="row g-0 small mb-4">
              <dt class="col-5 wdw-muted fw-medium">Best light</dt><dd class="col-7 fw-semibold mb-2">Sunrise</dd>
              <dt class="col-5 wdw-muted fw-medium">Mood</dt><dd class="col-7 fw-semibold mb-0">Moody and open</dd>
            </dl>
          </div>
        </div>
        <div class="vt-detail-item row g-4 g-lg-5 align-items-center" data-detail="7" hidden>
          <div class="col-lg-7"><img class="vt-photo w-100" src="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?w=1200&h=900&fit=crop&auto=format&q=70" width="1200" height="900" loading="lazy" alt="Sunset shore: warm light on the foam and a long, flat beach"></div>
          <div class="col-lg-5">
            <span class="badge rounded-pill bg-primary-subtle text-primary-emphasis mb-3">Water</span>
            <h2 class="wdw-heading h2 mb-3" tabindex="-1">Sunset shore</h2>
            <p class="wdw-muted mb-4">Warm light on the foam and a long, flat beach. Low tide gives you a mirror at your feet.</p>
            <dl class="row g-0 small mb-4">
              <dt class="col-5 wdw-muted fw-medium">Best light</dt><dd class="col-7 fw-semibold mb-2">Sunset</dd>
              <dt class="col-5 wdw-muted fw-medium">Mood</dt><dd class="col-7 fw-semibold mb-0">Soft and golden</dd>
            </dl>
          </div>
        </div>
        <div class="vt-detail-item row g-4 g-lg-5 align-items-center" data-detail="8" hidden>
          <div class="col-lg-7"><img class="vt-photo w-100" src="https://images.unsplash.com/photo-1469975692758-66d107a536cb?w=1200&h=900&fit=crop&auto=format&q=70" width="1200" height="900" loading="lazy" alt="Desert stars: sandstone towers glow against a night sky"></div>
          <div class="col-lg-5">
            <span class="badge rounded-pill bg-primary-subtle text-primary-emphasis mb-3">Wilderness</span>
            <h2 class="wdw-heading h2 mb-3" tabindex="-1">Desert stars</h2>
            <p class="wdw-muted mb-4">Sandstone towers glow against a night sky. A tripod, patience and a warm jacket are all you need.</p>
            <dl class="row g-0 small mb-4">
              <dt class="col-5 wdw-muted fw-medium">Best light</dt><dd class="col-7 fw-semibold mb-2">After dusk</dd>
              <dt class="col-5 wdw-muted fw-medium">Mood</dt><dd class="col-7 fw-semibold mb-0">Still and dry</dd>
            </dl>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>

Built on Bootstrap 5.3.8 with plain JavaScript — no jQuery. Supports light and dark mode via data-bs-theme.