View Transitions API
View Transitions give you an easier way, by allowing you to make your DOM change without any overlap between states, but create a transition animation between the states using snapshotted views.[2]
Here's some minimal starter JS:
function navigate(url) {
const update = () => { /* fetch HTML then update DOM */ };
return 'startViewTransition' in document
? document.startViewTransition(update).finished
: // Fallback for non-supporting browsers
update();
}
This adds a default fade animation, and can be customised using CSS:
::view-transition-old(root) {
animation: fade-out 100ms ease-out both;
}
::view-transition-new(root) {
animation: fade-in 300ms 100ms ease-out both;
}
You can also scope the transitions to a particular element using the
view-transition-name
property:
body {
view-transition-name: content;
}
::view-transition-group(content) {
--out-time: 100ms;
}
::view-transition-old(content) {
animation: fade-out var(--out-time) ease-out both;
}
::view-transition-new(content) {
animation: fade-in 300ms var(--out-time) ease-out both;
}
Also, by default, if a scope exists in both of the old and new pages, the browser will attempt to transition the two elements, no extra code needed!