View Transitions for Color UIs: Instant Theme Swaps Without Flicker

Theme toggles have a long-standing problem: the browser repaints all at once, and any image, gradient, or shadow flickers visibly during the swap. The View Transitions API fixes this in a single line of JavaScript.

The one-liner

function toggleTheme() {
if (!document.startViewTransition) {
document.documentElement.classList.toggle('dark');
return;
}
document.startViewTransition(() => {
document.documentElement.classList.toggle('dark');
});
}

That is the entire upgrade. The browser snapshots the page before your callback runs, applies the change, snapshots after, and cross-fades between the two. No CSS transitions on every token.

Customising the animation

By default, you get a 250ms cross-fade. Replace it with anything CSS can express:

::view-transition-old(root),
::view-transition-new(root) {
animation-duration: 400ms;
animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
}
@media (prefers-reduced-motion: reduce) {
::view-transition-old(root),
::view-transition-new(root) { animation: none; }
}

Notice the reduced-motion guard. Always include it - users with vestibular disorders should never be forced through a transition.

Circular reveal from the toggle button

Pair the API with clip-path for the "ink ripple" effect popularized by Material 3:

const x = event.clientX, y = event.clientY;
const r = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));
const t = document.startViewTransition(() => toggleClass());
t.ready.then(() => document.documentElement.animate(
{ clipPath: [`circle(0 at ${x}px ${y}px)`, `circle(${r}px at ${x}px ${y}px)`] },
{ duration: 500, pseudoElement: '::view-transition-new(root)' }
));

Why this matters for color tooling

Palette tools redraw everything on every change: swatches, gradient previews, contrast bars, exported tokens. Wrapping each apply in a view transition turns aggressive UI changes into something cinematic without any per-component animation work.

Browser support, today

Chrome, Edge, Opera and Safari 18 all ship same-document transitions. Firefox is in progress. The progressive-enhancement feature-check above means non-supporting browsers fall back to instant swaps - a degradation no one will notice.

Try the effect live: any theme toggle on this site uses View Transitions. Open Color Picker in two tabs - light and dark - and watch the difference.