The View Transitions API And Delightful UI Animations (Part 1) — Smashing Magazine


Animations are an essential part of a website. They can draw attention, guide users on their journey, provide satisfying and meaningful feedback to interaction, add character and flair to make the website stand out, and so much more!

On top of that, CSS has provided us with transitions and keyframe-based animations since at least 2009. Not only that, the Web Animations API and JavaScript-based animation libraries, such as the popular GSAP, are widely used for building very complex and elaborate animations.

With all these avenues for making things move on the web, you might wonder where the View Transitions API fits in in all this. Consider the following example of a simple task list with three columns.

This is a complex state-based animation, and it is exactly the sort of thing that the View Transitions API is designed to handle. Without it, we would need both the old state (i.e., the outgoing image) and the new state (i.e., the incoming image) to be present in the DOM. This is where complexity kicks in. It can be very difficult to handle and maintain states in the DOM and is not necessarily made much easier with other web APIs and/or a JavaScript animation library.

And if things weren’t daunting enough, keep in mind that JavaScript is the most expensive resource on the web and our transition would depend on whichever JavaScript animation library that we choose, which needs to load and parse before it executes. In other words, a transition like this could be very costly in build, accessibility, maintenance, and performance. You wouldn’t be blamed for questioning whether the cost of having the animation is worth the return.

But what if we could leave the extra baggage of dependencies at the door and rely on vanilla JavaScript and CSS? We could let the optimized browser API do all the heavy lifting while maintaining complete control over how transitions behave between states. That’s the value of the View Transitions API and why we need it. It trivializes the types of popular effects that currently require additional overhead.

It might sound simple, but that’s already a lot of heavy lifting that we don’t have to worry about anymore! All we have to do is take care of DOM updates and animation styles. The API also allows us to tap into those individual states and more and gives us full control over the animation using the CSS animation shorthand properties and its individual constituent properties.

Browser Support And Standards Status

In this article, we’re going to take a deep dive into the View Transitions API and explore its potential by building three fun and exciting real-life examples from scratch.

But before we get there, it’s certainly worth restating that the View Transitions API specification is in Candidate Recommendation Snapshot status. That means the CSS Working Group has published the working draft, the W3C has given it a “wide review,” and it is intended to become a formal W3C Recommendation. Until that happens, the specification will remain a Candidate Recommendation and is in a feedback period (that was scheduled to conclude on December 5, 2023).

So, the View Transitions API is not quite ready for prime time and should be used experimentally at the time of this writing. The latest versions of Chrome, Edge, Opera, and Android Browser currently support the API. Safari has taken a positive position on it, and there’s an open ticket for Firefox adoption. We have to wait for these last two browsers to formally support the API before using it in a production environment.

While we’re on the topic of the View Transition API’s specification and status, I’ll also note that the feature was initially called the “Shared Element Transitions API” before it was known as the View Transitions API. You will still see the old name pop up, particularly articles published in 2021 and 2022 that have not been updated.

Example 1: Crossfade UI State Changes

Let’s start with a relatively simple yet fun example involving a grid of card components. The idea is that clicking on a card’s image expands the image in a sort of lightbox or modal fashion without leaving the current page.

Let’s start with the following markup:



Vast, still lake on a sunny day.
Peyto Lake, Canada

You can get the full markup, styles, and scripts from the following CodePen. The basic idea is that we have a

element that serves as a grid container that contains a series of

elements that are styled as card components.

See the Pen [Image gallery v2 – 1 – starting markup [forked]](https://codepen.io/smashingmag/pen/VwRZoxV) by Adrian Bece.

See the Pen Image gallery v2 – 1 – starting markup [forked] by Adrian Bece.

Let’s take a closer look at JavaScript:

const overlayWrapper = document.getElementById("js-overlay");
const overlayContent = document.getElementById("js-overlay-target");

function toggleImageView(index) {
  // Get the image element by ID.
  const image = document.getElementById(`js-gallery-image-${index}`);

  // Store image parent element.
  const imageParentElement = image.parentElement;

  // Move image node from grid to modal.
  moveImageToModal(image);

  // Create a click listener on the overlay for the active image element.
  overlayWrapper.onclick = function () {
    // Return the image to its parent element
    moveImageToGrid(imageParentElement);
  };
}

// Helper functions for moving the image around and toggling the overlay.
function moveImageToModal(image) {
  // Show the overlay
  overlayWrapper.classList.add("overlay--active");
  overlayContent.append(image);
}

function moveImageToGrid(imageParentElement) {
  imageParentElement.append(overlayContent.querySelector("img"));
  // Hide the overlay.
  overlayWrapper.classList.remove("overlay--active");
}

On card click, we are moving the image element from the grid markup into the overlay, leaving the container node empty. We are also setting the overlay onclick event — which moves the image back into its origin container — as well as toggling the visibility CSS class on the overlay element.

It’s important to note that we are moving the image element from the

element that is contained in the
container into an

Scroll to Top