SPA view transitions land in Chrome 111

SPA view transitions land in Chrome 111

The View Transition API lets you update the DOM in a single step, while generating an animated transition between the two states.

Transitions created with the View Transition API. Try the demo site–Requires Chrome 111+.

In our efforts to work on future enhancements to this feature, we broke it in Chrome Canary. Oops! But hey, that’s what Canary’s for. If you want to try view transitions today, use stable Chrome 111, or beta Chrome 112.

These kinds of transitions were a frequently-requested feature from developers, including me, and I think we’ve managed to land it in a way that balances good defaults with extensibility and customization. That sounds like we’re patting ourselves on the back, but developer feedback was key to the design of this feature. An earlier prototype of this feature was much less flexible, and folks (like you?) who took the time to play with the prototypes and provide feedback triggered a total rethink. Thank you!

To get to grips with the feature, and play with some demos, check out our guide. If there’s something you feel isn’t covered there, please reach out to me on Twitter, Mastodon, or via email.

The View Transition API is currently only available in Chrome; thankfully it can be used as a progressive enhancement. The guide includes a helper function that you can use across browsers, but only browsers that support view transitions will get the animation.

We developed this feature within the CSS Working Group, with input from other browser vendors and independents. We don’t know if or when other browsers will adopt View Transitions, but keep an eye on Mozilla’s standards position, and WebKit’s standards position.

But, we’re not ‘done’ yet!

The functionality landing in Chrome 111 is just the first release. We hope we’ve already found all the bugs, but please file any issues you find at, preferably with a reduced demo. If that’s not something you’re familiar or comfortable with, reach out to me on Twitter, Mastodon or via email, and I’ll help.

This release is a small-but-hopefully-useful part of a bigger picture. We’ve already sketched some extensions to this feature to ensure the parts we’re shipping today are future-compatible.

Here’s a sneak preview of what we’re thinking. These aren’t in priority order (well, maybe the first one is the most important for a lot of folks), so we’d love feedback on which additions are the most important to you.

Transitions across documents

This is the one I think most developers want us to work on next, and the good news is that we’re already working on it!

The View Transitions API was designed so it can work across same-origin documents. The only difference is, instead of startViewTransition signaling the DOM state change, the navigation itself will signal that change.

Our prototype of this behind the chrome://flags/#view-transition-on-navigation flag. Here’s a super-simple demo, and a more complex demo.

To move this forward we need to figure out how each page opts into the transition. Right now we’re using a meta tag: <meta name="view-transition" content="same-origin">, but we think CSS is a better place for this. We also want to make it easier to know what kind of page you’re transitioning from, preferably without needing to write JavaScript.

There’s lots of work to do, and we’d rather land it ‘right’ than ‘fast’, but it’s definitely a priority for us.

Compositor-driven animations

We chose to animate width and height on transition groups by default because it’s much easier to customize. However, this means the animation runs on the main thread, which isn’t ideal, particularly during page loads.

We plan to detect the default animations and common customizations, then reinterpret them as compositor-driven animations for a nice performance boost.

Scoped transitions

Right now, SPA transitions are scoped to the whole document, and only one transition can run at a time. We want to introduce a feature that allows transitions to be scoped to a particular element so that multiple page components can run transitions independently.

This would allow, say, an embedded video player to use view transitions, at the same time as an embedded chat widget.

Nested transition groups

Right now, all ::view-transition-groups are siblings. This is often a good thing, as it allows views to transition from one container to another, and you don’t have to worry about clipping.

However, sometimes you want a view to be clipped by some parent, which may also be involved in the transition.

We want to investigate an opt-in that places a particular ::view-transition-group within another ::view-transition-group.

Classes of transitions

Each view-transition-name must be unique. That’s how we identify that a particular element is conceptually “the same” on either side of the DOM change, even if it isn’t literally the same element.

However, sometimes things with different view-transition-names should use the same kind of animation. Right now, this means adding a selector rule for every view-transition-name.

We’d like to add a way to create classes of transitions to overcome this limitation.

Ignore offscreen elements

If you give an element a view-transition-name, it will be involved in the transition as its own group. Sometimes this isn’t ideal. For example, if you give a header a view-transition-name, and you go from a state where you’re scrolled down by 2000 pixels, to a state at the top of the page, the header will animate from 2000 pixels away, which feels wrong in terms of timing.

Instead, we’d like to add an opt-in where an element will be ignored, as if it doesn’t have a view-transition-name, if it’s entirely outside the viewport.

You can already do this with JavaScript by dynamically setting style.viewTransitionName, but it feels like we should have a declarative solution for this.

requestAnimationFrame-driven animations

You can already create view transition animations with JavaScript via the web animations API, but sometimes you need to drive things frame-by-frame with requestAnimationFrame.

You can already do that, but it’s a bit hacky. Here’s a demo with some helpers you might find useful. We want to make it not-hacky!

We’ll do this in two parts. One, by providing an API to indicate when the animation is done. And two, by providing JavaScript access to pseudo-elements. That second part might be a pretty big job, but it feels like the right thing to do in the long term.

Now go make some great view transitions!

Hopefully, like me, you’re excited about the present and future of this feature. If you have any feedback, or just want to show off some view transitions you made, be they smooth and functional, or just plain silly, please reach out to me on Twitter or Mastodon!

This post is also available in: English