Advertisement

Native Cross-Fade View Transition Gallery

| by Vladimir | 2 min read | code by Chen Hui Jing
Beginner

Tech & Dependencies

HTML CSS JavaScript

Features

  • View Transitions
  • Cross-Fade
  • Event Delegation
  • Feature Detection

Browser Support

Chrome 111+ Edge 111+ Firefox 131+ Safari 18+

Core

This is a Native Cross-Fade View Transition Gallery. It updates a central image source triggered by thumbnail interactions. Its function is to smooth out abrupt visual DOM updates using the browser’s built-in rendering engine, entirely eliminating the need for external animation payloads or CSS opacity toggles.

Specs

  • Weight: ~1 KB. Zero dependencies.
  • Performance: High. The browser handles the rasterized cross-fade at the system level.
  • Theming / Customization: Controlled entirely by standard CSS. The transition effect requires zero custom animation code because startViewTransition defaults to a cross-fade.
  • Responsiveness: Native CSS flexbox logic.
  • Web APIs: View Transitions API.
  • Graceful Degradation: Flawless. Implements strict JavaScript feature detection (if (!document.startViewTransition)). In older browsers, the image source swaps instantly. A CSS @supports query is also included to display an unsupported notification. [!] Thumbnails use anchor tags with href="#", which can cause unwanted page scrolling if default behaviors are not prevented.

Anatomy

  • HTML: A semantic structure utilizing <main>, <figure>, and a <ul> for the thumbnail list.
  • CSS: Purely structural. Flexbox manages the alignment of the thumbnails relative to the main image. Includes a targeted @supports block to handle browsers missing the View Transitions API.
  • JS: The logic controller. It binds a single delegated event listener to the .thumbnails container, identifies the clicked image, and executes the DOM update.

Logic

The efficiency of this snippet lies in its minimal intervention. The script delegates the heavy lifting directly to the browser.

if (!document.startViewTransition) {
  displayNewImage();
  return;
}

const transition = document.startViewTransition(() => displayNewImage());

Instead of tracking current/next states, manipulating CSS opacity classes, or running requestAnimationFrame loops, the code simply wraps the DOM mutation (displayNewImage()) inside startViewTransition. The browser automatically captures the visual state before the callback, executes the DOM change synchronously, captures the new state, and generates a fluid cross-fade between the two snapshots.

Feel

Instant and native. Because the browser handles the raster interpolation, the swap feels weightless and deeply integrated with the OS rendering pipeline. It removes the harsh, jarring cut typical of standard src updates while maintaining absolute minimalism in the codebase.

Advertisement