View Transitions
Overview
The View Transitions API is perhaps the most magical addition to CSS in a decade. Traditionally, when you navigate from page1.html to page2.html, the browser aggressively wipes the screen white and loads the new page. View Transitions allow the browser to take a 'screenshot' of the old page, a 'screenshot' of the new page, and smoothly crossfade them natively. Furthermore, it can intelligently identify shared elements (like an image thumbnail on page 1 and a hero banner on page 2) and mathematically morph them across the screen during the navigation.
Syntax
/*
1. The API is usually triggered via JS (or <meta> tags for cross-document).
document.startViewTransition(() => updateTheDOM());
*/
/* 2. Identifying Shared Elements in CSS */
/* On Page 1 (The thumbnail) */
.gallery-thumbnail {
/* Give the element a strictly unique name */
view-transition-name: hero-image;
}
/* On Page 2 (The full-size hero banner) */
.hero-banner {
/* Give it the exact same name! */
view-transition-name: hero-image;
}
/*
The browser will now instantly calculate the math to physically fly
the thumbnail across the screen and expand it into the hero banner
during the page load!
*/Common Pitfalls
- Using the same
view-transition-nameon multiple elements at the exact same time. The browser relies on the name being a strictly unique ID to calculate the morphing math. If two elements share a name, the entire transition algorithm immediately aborts and crashes. - Ignoring accessibility. Massive, screen-spanning morphing animations can easily trigger motion sickness. You must wrap view transition CSS inside a
@media (prefers-reduced-motion: no-preference)block to protect users.
Interview Questions
When triggered, it halts rendering and captures the old DOM state as a rasterized snapshot. It then updates the DOM, captures a new snapshot, and creates a pseudo-element tree (::view-transition-group) floating on top of the page. It then uses standard CSS animations to crossfade or morph those snapshots.
Real-World Example
Customizing the default crossfade animation to be a slow, cinematic fade.
/* Targeting the native pseudo-elements created by the API */
::view-transition-old(root),
::view-transition-new(root) {
/* Slow the crossfade down to 1 second */
animation-duration: 1s;
}
::view-transition-new(root) {
/* Make the new page scale up slightly as it fades in */
animation-name: custom-fade-in;
}
@keyframes custom-fade-in {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}Check Your Knowledge
Test your understanding of View Transitions with these quick questions.