webdevpuneet.com

View Transition API Carousel — HTML CSS JS Snippet

View Transition API Carousel · Carousels · Plain HTML, CSS & JS · Live preview

Copy & paste

Source Code

<div class="vtc-wrap">
  <div class="vtc-stage" id="vtcStage">
    <div class="vtc-slide" style="background:linear-gradient(160deg,#6366f1,#4338ca)"><span>🎧</span><h3>Headphones</h3></div>
  </div>
  <div class="vtc-controls">
    <button class="vtc-btn" id="vtcPrev" aria-label="Previous">‹</button>
    <div class="vtc-dots" id="vtcDots"></div>
    <button class="vtc-btn" id="vtcNext" aria-label="Next">›</button>
  </div>
  <p class="vtc-support" id="vtcSupport"></p>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Uses the real browser View Transitions API — document.startViewTransition — not a hand-rolled animation
Zero keyframes, zero CSS transitions, zero JS-driven transform math for the slide-change animation itself
One CSS declaration (view-transition-name) is the entire animation setup
Graceful feature detection — falls back to an instant, fully functional swap in unsupported browsers
The browser automatically interpolates position, size, and appearance between the before/after DOM snapshots
Dots, arrows, and keyboard navigation all route through the same update() function uniformly

About this UI Snippet

View Transition API Carousel — The Browser Animates the Diff, Not You

Screenshot of the View Transition API Carousel snippet rendered live

Every other carousel in this library animates a transition by hand — a transform, an opacity, a keyframe. This one hands that job to the browser itself: document.startViewTransition(callback) snapshots the DOM as it is right now, runs the callback (which just replaces the slide's HTML — no animation code inside it at all), snapshots the DOM again afterward, and then automatically cross-fades and morphs between the two snapshots for any element carrying a matching view-transition-name.

One CSS property is the entire animation setup

The *only* animation-related code in this snippet is view-transition-name: vtc-active-slide on .vtc-slide in the CSS. That single declaration tells the browser "treat this element as a named subject to animate between states" — there's no transition, no @keyframes, no JS-driven transform anywhere in the slide-change logic. paint() just tears down the old slide's markup and writes in the new one synchronously; the browser handles everything about *how* that change appears.

Feature detection, not a hard dependency

Because the View Transitions API isn't universal yet, every call is guarded: typeof document.startViewTransition === 'function'. When it's missing, update() just calls paint() directly — the carousel still works, it simply swaps instantly instead of animating. That's a deliberate progressive-enhancement pattern: the feature adds polish where supported and never breaks functionality where it isn't.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA support note tells you whether your browser has the View Transitions API; the first slide appears.
  2. 2
    Click the arrowsIn a supporting browser, the slide smoothly cross-fades and morphs into the next one — no hand-written animation.
  3. 3
    Click a dotJump directly to that slide, with the same automatic browser-driven transition.
  4. 4
    Try it in an unsupported browserThe carousel still works perfectly — it just swaps instantly instead of animating.
  5. 5
    Inspect the CSSNotice there's no transition or @keyframes rule driving the slide change at all — just one view-transition-name declaration.

Real-world uses

Common Use Cases

Modern-browser-first product pages
Ship a polished native-feeling transition with almost no animation code to maintain.
Learning the View Transitions API
One of the clearest minimal examples of startViewTransition applied to a real, common UI pattern.
Progressive enhancement showcases
Demonstrates a feature that enhances supporting browsers without breaking unsupported ones.
Lightweight content rotators
Get smooth, correct-looking transitions without shipping any custom animation logic at all.

Got questions?

Frequently Asked Questions

It marks an element as a named "subject" the browser should track across a startViewTransition call — if an element with that same name exists in both the before and after DOM snapshots, the browser automatically animates between its old and new state (position, size, opacity) rather than treating it as an unrelated element being removed and added.

The feature is checked with typeof document.startViewTransition === "function" before use — when it's missing, paint() is called directly with no wrapping transition call, so the carousel still functions correctly, just without the animated cross-fade/morph.

Yes — give the icon, the title, and the background each their own unique view-transition-name, and the browser will animate each one's before/after state independently rather than treating the whole slide as one blob.

Yes, in supporting browsers it also works for full page navigations (same-document or cross-document), which is a separate but related use of the same API — this snippet demonstrates the single-page, same-document version.

Arrows and dots are real labeled buttons, fully keyboard-operable via Left/Right arrow keys; consider also checking prefers-reduced-motion and skipping startViewTransition's animation (calling paint() directly) for users who've requested reduced motion.