The new View Transitions API offers an easier way to animate between two DOM states — even between page loads. It’s a progressive enhancement that works today.
CSS transitions and animations have revolutionized web effects over the past decade, but not everything is easy. Consider a list of elements — such as ten images with titles — which we want to transition into a new list of elements using a cross-fade. The current approach:
- retain the old DOM elements
- build the new DOM elements, append them to the page, ensuring they’re in an appropriate location
- fade out the old set while fading in the new set, then
- (optionally) replace the old DOM elements with the new
It’s not been possible to simply update the DOM — until now! The View Transitions API uses the following process:
- The API takes a snapshot of the current page state.
- We update the DOM adding or removing elements as necessary.
- The API takes a snapshot of the new page state.
- The API animates between the two states, using a default fade or whatever CSS animations we define.
We only need to update the DOM as we’re already doing. A few lines of additional code can progressively enhance the page when the View Transitions API is available to create presentation-like effects.
The API is experimental, but recent Chromium-based browsers support in-page, single-document DOM-based effects.
A viewTransition API for navigations is also available in Chrome 115+ and offers animations between individual page loads — such as on typical WordPress sites. This is even easier to use and requires no JavaScript.
Mozilla and Apple haven’t revealed their intentions for implementing the API in Firefox and Safari. Any browser without the View Transitions API will continue to work, so it’s safe to add effects today.
New Old Techniques
Developers of a certain age may be experiencing déjà vu. Microsoft added element and whole page transitions in Internet Explorer 4.0 (released in 1997) with further updates in IE5.5 (released in 2000). We could add PowerPoint-inspired boxes, circles, wipes, dissolves, blinds, slides, strips, and spirals with a <meta>
tag:
<meta http-equiv="Page-Enter" content="progid:DXImageTransform.Microsoft.Iris(Motion='in', IrisStyle='circle')">
<meta http-equiv="Page-Exit" content="progid:DXImageTransform.Microsoft.Iris(Motion='out', IrisStyle='circle')">
Strangely, the technique never became widely adopted. It wasn’t a web standard, but the W3C was in its infancy — and developers were happy to use plenty of other IE-specific technologies!
Why has it taken a quarter of a century for an alternative to appear?!
Creating In-page Transitions
View the following CodePen example in Chrome and click the navigation in the header to see a one-second fade between the two states.
See the Pen Transitions API example 1 by SitePoint (@SitePoint) on CodePen.
The HTML page has two <article>
elements with the IDs article1
and article2
for the blocks of content:
<main><div id="articleroot">
<article id="article1">
<h2>Article 1 content</h2>
<figure>
<img src="image1.jpg" width="800" height="500" alt="image" />
</figure>
<p>Lorem ipsum dolor sit amet...</p>
</article>
<article id="article2">
<h2>Article 2 content</h2>
<figure>
<img src="image2.jpg" width="800" height="500" alt="image" />
</figure>
<p>Ut pretium ac orci nec dictum...</p>
</article>
</div></main>
A switchArticle()
function handles all DOM updates. It shows or hides each article by adding or removing a hidden
attribute. On page load, the active article is determined from the page URL’s location.hash
or, if that’s not set, the first <article>
element:
// get all articles in page
const article = document.getElementsByTagName('article');
// show one article on page load
switchArticle();
// show active article
function switchArticle(e) {
const hash = e?.target?.hash?.slice(1) || location?.hash?.slice(1);
Array.from(article).forEach((a, i) => {
if (a.id === hash || (!hash && !i)) {
a.removeAttribute('hidden');
}
else {
a.setAttribute('hidden', '');
}
});
}
An event handler function monitors all page clicks and calls switchArticle()
when the user clicks a link with a #hash
:
// navigation click event
document.body.addEventListener('click', e => {
if (!e?.target?.hash) return;
switchArticle(e);
});
We can now update this handler to use View Transitions by passing the switchArticle()
function as a callback to document.startViewTransition()
(checking the API is available first):
document.body.addEventListener('click', e => {
if (!e?.target?.hash) return;
if (document.startViewTransition) {
// use View Transition effect
document.startViewTransition(() => switchArticle(e));
}
else {
// View Transition not available
switchArticle(e);
}
});
document.startViewTransition()
takes a snapshot of the initial state, runs switchArticle()
, takes a new snapshot of the new state, and creates a default half-second fade between the two.
The following selectors are available in CSS to target the old and new states:
::view-transition-old(root) {
/* animate out effects */
}
::view-transition-new(root) {
/* animate in effects */
}
The example above increases the animation duration to one second so the fade effect is more noticeable:
::view-transition-old(root),
::view-transition-new(root) {
animation-duration: 1s;
}
A view-transition-group(root)
can apply effects to both old
and new
states at the same time, although we’re unlikely to apply the same animation in most cases.
Asynchronous DOM Updates
The callback passed to document.startViewTransition()
can return a promise so asynchronous updates are possible. For example:
document.startViewTransition(async () => {
const response = await fetch('/some-data');
const json = await response.json();
doDOMUpdates(json);
await sendAnalyticsEvent();
});
This freezes the page until the promise fulfills, so delays could impact the user experience. It’s more efficient to run as much code as possible outside the call to .startViewTransition()
. For example:
const response = await fetch('/some-data');
const json = await response.json();
document.startViewTransition(() => doDOMUpdates(json));
await sendAnalyticsEvent();
Creating More Sophisticated Transitions
The following CodePen demo adds a nicer animation using the ::view-transition-old(root)
and ::view-transition-new(root)
selectors.
See the Pen Transitions API example 2 by SitePoint (@SitePoint) on CodePen.
The CSS defines transition-out
and transition-in
animations with fading and rotation:
::view-transition-old(root) {
animation: 1s transition-out 0s ease;
}
::view-transition-new(root) {
animation: 1s transition-in 0s ease;
}
@keyframes transition-out {
from {
opacity: 1;
translate: 0;
rotate: 0;
}
to {
opacity: 0;
translate: -3rem -5rem;
rotate: -10deg;
}
}
@keyframes transition-in {
from {
opacity: 0;
translate: 3rem 5rem;
rotate: -10deg;
}
to {
opacity: 1;
translate: 0;
rotate: 0;
}
}
The animations apply to the whole page — including the <header>
element, which looks a little strange. We can apply animations (or no animation) to individual elements by setting a view-transition-name
:
header {
view-transition-name: header;
}
We can now target that element and apply a different animation:
::view-transition-old(header) {
}
::view-transition-new(header) {
}
In this case, we don’t want the header to have any effects, so it’s not necessary to define any animation. The ::view-transition-old(root)
and ::view-transition-new(root)
selectors now apply to all elements except for the <header>
. It remains in-place.
See the Pen Transitions API example 3 by SitePoint (@SitePoint) on CodePen.
Because we’re defining effects in CSS, we can use developer tool features such as the Animations panel to examine and debug our animations in more detail.
Using the Web Animations API
While CSS is enough for most effects, the Web Animations API permits further timing and effect control in JavaScript.
document.startViewTransition()
returns an object that runs a .ready
promise which resolves when the transition old
and new
pseudo-elements are available (note the pseudoElement
property in the second .animate()
parameter):
// use the Web Animations API
const transition = document.startViewTransition( doDOMupdate );
transition.ready.then( () => {
document.documentElement.animate(
[
{ rotate: '0deg' },
{ rotate: '360deg' },
],
{
duration: 1000,
easing: 'ease',
pseudoElement: '::view-transition-new(root)',
}
);
});
Creating Multi-page Navigation Transitions
We can also use View Transitions as the user navigates between page loads on multi-page applications (MPA) such as typical WordPress sites. It’s known as the viewTransition API for navigations
, which we must enable in chrome://flags/
in Chrome 115 (currently the Canary nightly build for developers). The flag is also available in previous releases of the browser, but the API may be missing or unstable.
The process is easier than in-page transitions because it’s enabled with a single meta tag in the HTML <head>
:
<meta name="view-transition" content="same-origin" />
We can then define ::view-transition-old
and ::view-transition-new
CSS selectors in an identical way to those shown above. We don’t require any JavaScript unless we want to use the Web Animations API.
The navigations API may or may not be enabled by default when Chrome 115 final is released. We can use the technique today because browsers that don’t support the API will fall back to standard, non-animated page loads.
Disabling Animations
Animations can trigger discomfort for some people with motion disorders. Most operating systems provide a user preference setting to disable effects. We can detect this with the CSS prefers-reduced-motion
media query and switch off animations accordingly:
@media (prefers-reduced-motion) {
::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
animation: none !important;
}
}
Summary
The View Transitions API simplifies animations when altering element states in-page and between page loads. Transitions of this type were possible before, but they required a considerable amount of JavaScript — and we had to be careful not to break browser navigation such as the back button.
The API is new. There’s no guarantee it will remain unchanged, become a W3C standard, or have implementations in Firefox and Safari. However, we can use the API today because it’s a progressive enhancement. Our applications will continue to work in browsers which don’t support the API; they just won’t show animations. There’s a risk certainty the API will change but, even if we have to do some maintenance, our old code shouldn’t break the site and updates are likely to be minimal.
The downside? The API could lead to an explosion of annoyingly long and wild animations across the Web because site owners consider them to be “on-brand”! Ideally, animations should be fast and subtle to highlight a UI change. Less is often more.
Further references:
- Chrome Developers: Smooth and simple transitions with the View Transitions API: lots of examples, suggestions, and techniques
- MDN: View Transitions API
- W3C: CSS View Transitions Module Level 1
Frequently Asked Questions (FAQs) about View Transitions API
What is the View Transitions API and how does it work?
The View Transitions API is a web-based interface that allows developers to create smooth, seamless transitions between different views or states of a web application. It works by providing a set of methods and properties that developers can use to define and control the behavior of transitions. This includes the ability to specify the duration, timing function, and delay of a transition, as well as the ability to pause, resume, or cancel a transition in progress.
How can I use the View Transitions API in my web application?
To use the View Transitions API in your web application, you first need to include it in your project. This can be done by adding a reference to the API in your HTML file. Once the API is included, you can use its methods and properties to define and control transitions. For example, you can use the transition
property to specify the duration, timing function, and delay of a transition, and the pause
, resume
, and cancel
methods to control a transition in progress.
What are the benefits of using the View Transitions API?
The View Transitions API offers several benefits for web developers. First, it allows for the creation of smooth, seamless transitions between different views or states of a web application, which can enhance the user experience. Second, it provides a high level of control over the behavior of transitions, allowing developers to fine-tune the appearance and timing of transitions to suit their needs. Finally, the API is web-based, meaning it can be used in any web application, regardless of the underlying technology stack.
Are there any limitations or drawbacks to using the View Transitions API?
While the View Transitions API is a powerful tool for creating transitions, it does have some limitations. For example, it may not be supported by all browsers, particularly older ones. Additionally, while the API provides a high level of control over transitions, it can also be complex to use, particularly for developers who are not familiar with its methods and properties. Finally, like any API, it can be subject to changes and updates, which may require developers to update their code to maintain compatibility.
Can I use the View Transitions API with other web technologies?
Yes, the View Transitions API can be used in conjunction with other web technologies, such as HTML, CSS, and JavaScript. In fact, it is designed to be used as part of a larger web development toolkit, complementing and enhancing the capabilities of these other technologies. For example, you can use the API to create transitions that are triggered by JavaScript events, or to animate changes to CSS properties.
How can I learn more about the View Transitions API?
There are several resources available for learning more about the View Transitions API. These include the official API documentation, which provides a comprehensive overview of the API’s methods and properties, as well as tutorials and examples that demonstrate how to use the API in practice. Additionally, there are numerous online communities and forums where developers can share tips and tricks, ask questions, and get help with using the API.
What are some examples of applications that use the View Transitions API?
The View Transitions API is used in a wide range of web applications, from simple websites to complex web-based applications. For example, it can be used to create transitions between different pages of a website, or between different states of a web-based game or interactive application. It can also be used to animate changes to the layout or appearance of a web page, such as expanding or collapsing a menu, or changing the color of a button.
How can I troubleshoot issues with the View Transitions API?
If you’re experiencing issues with the View Transitions API, there are several steps you can take to troubleshoot the problem. First, check the API documentation to ensure you’re using the methods and properties correctly. Second, use a web development tool such as Chrome DevTools to inspect your code and identify any errors. Finally, consider reaching out to the online developer community for help. Many developers are willing to share their expertise and may be able to provide insights or solutions to your problem.
Can I use the View Transitions API on mobile devices?
Yes, the View Transitions API is designed to be used on both desktop and mobile devices. However, keep in mind that the performance and behavior of transitions may vary depending on the device and browser. It’s always a good idea to test your transitions on multiple devices and browsers to ensure they work as expected.
Is the View Transitions API free to use?
Yes, the View Transitions API is a free, open-source technology. This means you can use it in your projects without having to pay any licensing fees. However, as with any open-source technology, it’s important to understand and comply with the terms of the API’s license, which may require you to share any modifications you make to the API or to attribute the original creators.
Craig is a freelance UK web consultant who built his first page for IE2.0 in 1995. Since that time he's been advocating standards, accessibility, and best-practice HTML5 techniques. He's created enterprise specifications, websites and online applications for companies and organisations including the UK Parliament, the European Parliament, the Department of Energy & Climate Change, Microsoft, and more. He's written more than 1,000 articles for SitePoint and you can find him @craigbuckler.