Look at the View Transition API
I'm exited about a new browser API: View Transition API. This API allows us to create an animated transition between two pages (in multi-page application) or views (in single-page application). And I must say, it works pretty nice!
In this post, I'll cover the basics of how the View Transition API works, with a focus on creating transitions between two separate pages (documents).
The View Transition API is currently not available in all browsers.
Enable a view transition
To enable a view transition between two separate pages (documents), two key requirements must be met:
- Both pages must have the same origin. The URL must have the same scheme, hostname (and port).
- Both pages need to include the CSS
@view-transitionat-rule somewhere.
The at-rule must be present on both pages and should contain the 'navigation' property with the value 'auto'.
@view-transition {
navigation: auto;
}
Default transition
Assume a situation where there are two pages and the requirements are met. The first page contains a link to the second page and the user clicks on that link.
An animation occurres and the second page gets visible with short cross-fade effect. The opacity of the old page goes from 1 to 0 and the opacity of the new page goes from 0 to 1.

This is the default animation, but we can make it more interesting by adding some CSS. But let us first look at the process of what is actually happening.
Process
When the user clicks on a link to navigate to another page, the following things are happening:
- The View Transition API takes a snapshot of the current page.
- The browser makes a request to load the next page.
- After the page has been downloaded, the View Transition API takes a snapshot of the new page.
- The View Transition API animates between the current and new state.
Snapshots
When the second page (document) has been loaded, it will appear in the browser with some nested pseudo-elements which contains snapshots of both pages.
See this example, where I have created a view transition with a duration of 6 seconds:

The parent ::view-transition-group(root) element contains the following elements:
The ::view-transition-old(root) element shows a static snapshot of the previous (old) page.
The ::view-transition-new(root) element shows a live representation of the next (new) page.
These are the default pseudo-elements that will be created when navigating between two pages, indicated by the root transition group name.
These pseudo-elements are removed from the page, when the animation has completed.
Create custom transition animation
Now we have the pseudo-elements with both states, we can use them in CSS to create our own animation.
This is an example of a CSS transition I have made:
/* Enable view transition */
@view-transition {
navigation: auto;
}
/* Animation for previous page */
@keyframes fancy-anim-out {
0% {
opacity: 1;
z-index: 2;
}
50% {
z-index: 1;
}
100% {
opacity: 0;
scale: 0;
transform: translateX(-120%);
z-index: 1;
}
}
/* Animation for next page */
@keyframes fancy-anim-in {
0% {
transform: translateX(100%);
z-index: 1;
}
100% {
transform: translateX(0);
z-index: 2;
}
}
/* Assign animation to pseudo-element (snapshot) of previous page */
::view-transition-old(root) {
animation-name: fancy-anim-out;
}
/* Assign animation to pseudo-element (snapshot) of next page */
::view-transition-new(root) {
animation-name: fancy-anim-in;
}
/* Set duration of the animations */
::view-transition-group(root) {
animation-duration: 2s;
}
See the transition in action:

Transition groups
Because the pseudo-elements are added to the page, you can create an animation for the whole page. You can also create animated transitions for specific elements on the pages, instead of the whole page as one.
To do this, you you need to create a transition group by adding view-transition-name with a custom name in CSS to a selector that targets a specific element you want to animate.
header.page-header {
/* This creates a transition group with the name 'my-header'. */
view-transition-name: my-header;
}
For every transition group you define in CSS, there will be a ::view-transition-group pseudo-element with the defined name. The transition group has a ::view-transition-old when the current page contains the element. And has a ::view-transition-new element when the next page contains the element.

Because we now have these pseudo-elements available during the transition, we can use CSS to define animations for every group.
An example in CSS:
/* Define transition groups. */
div.blog-post-image {
view-transition-name: post-image;
}
div.blog-post-intro {
view-transition-name: post-intro;
}
/* Define animations. */
@keyframes post-image-anim-in {
0% {
opacity: 0;
transform: scale(0.2);
}
100% {
opacity: 1;
transform: scale(1);
}
}
@keyframes post-image-anim-out {
0% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.2);
}
}
@keyframes post-intro-anim-in {
0% {
opacity: 0;
transform: translateX(100%);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
@keyframes post-intro-anim-out {
0% {
opacity: 1;
transform: translateX(0);
}
100% {
opacity: 0;
transform: translateX(100%);
}
}
/* Assign the animations to the pseudo-elements (states). */
::view-transition-new(post-image) { animation-name: post-image-anim-in; }
::view-transition-old(post-image) { animation-name: post-image-anim-out; }
::view-transition-new(post-intro) { animation-name: post-intro-anim-in; }
::view-transition-old(post-intro) { animation-name: post-intro-anim-out; }
/* Set duration of the animations. */
::view-transition-group(post-image) { animation-duration: 0.5s; }
::view-transition-group(*) { animation-duration: 1s; }
This is a visual example of a transition in which multiple transition groups are used:

Animate, but don't overdo it
I think that a transition animation can really make a website feel smoother, polished and more pleasant to use, as long as it is kept subtle. Too much movement can become distracting (like I did in my examples). So be careful not to go over the top when defining an animation.
Project with demos
I've created a project on GitHub that includes demos showcasing how to use the View Transition API: GitHub - View Transition API demos
Conclusion
I had a great time exploring this new browser API. It's relatively easy to create a cool animation between two pages, without doing crazy things with JavaScript. I hope that this API will be adopted by other browsers.
References
Chrome for developers - Cross-document view transitions for multi-page applications