Skip to main content

View Transitions

Weblisk wraps the browser's View Transitions API with automatic fallbacks, making smooth page transitions trivial.

Basic Navigation

js
import { navigate } from 'weblisk/nav/transition.js';

document.querySelector('a.fancy').addEventListener('click', async (e) => {
  e.preventDefault();
  await navigate(e.target.href);
});

Transition Types

Tag transitions with types for targeted CSS:

js
await navigate('/gallery', { types: ['slide-left'] });
css
::view-transition-old(root).slide-left {
  animation: slide-out-left 0.3s ease;
}
::view-transition-new(root).slide-left {
  animation: slide-in-right 0.3s ease;
}

Named Elements

Match elements across pages for shared element transitions:

js
import { transitionNames } from 'weblisk/nav/transition.js';

transitionNames({
  '.product-image': 'product-hero',
  '.product-title': 'product-title',
});

The browser automatically animates matching elements between the old and new page.

SPA-Style Swap

Use a callback to swap content manually:

js
await navigate(async () => {
  const html = await fetch('/about').then(r => r.text());
  document.querySelector('main').innerHTML = html;
});

MPA Transitions

For multi-page apps (the default Weblisk pattern), add this CSS to your stylesheet to enable smooth crossfade transitions between pages. Both pages must include this rule:

css
@view-transition { navigation: auto; }

/* Customize the animation */
::view-transition-old(root) {
  animation: 200ms ease both fade-out;
}
::view-transition-new(root) {
  animation: 200ms ease both fade-in;
}

This is already included in the scaffold's styles.css. No JavaScript needed for MPA transitions.

SPA Transitions

For single-page apps that swap content dynamically, use navigate() with a callback:

js
import { navigate } from 'weblisk/nav/transition.js';

// Swap content with a view transition
await navigate(() => {
  document.getElementById('content').innerHTML = newHTML;
});

Falls back to a CSS crossfade on browsers without the View Transitions API.