Add view transitions to your website

I must admit, when Jake told me he was leaving Google, I got very worried about the future of the View Transitions API.

To recap: Chrome shipped support for the API, but only for single page apps. That had me worried:

If the View Transitions API works across page navigations, it could be the single best thing to happen to the web in years.

If the View Transitions API only works for single page apps, it could be the single worst thing to happen to the web in years.

Well, the multi-page version still hasn’t yet shipped in Chrome stable, but it is available in Chrome Canary behind a flag, so it looks like it’s almost here!

Robin took the words out of my mouth:

Anyway, even this cynical jerk is excited about this thing.

Are you the kind of person who flips feature flags on in nightly builds to test new APIs?

Me neither.

But I made an exception for the View Transitions API. So did Dave:

I think the most telling predictor for the success of the multi-page View Transitions API – compared to all other proposals and solutions that have come before it – is that I actually implemented this one. Despite animations being my bread and butter for many years, I couldn’t be arsed to even try any of the previous generation of tools.

Dave’s post is an excellent step-by-step introduction to using view transitions on your website. To recap:

Enable these two flags in Chrome Canary:

chrome://flags#view-transition
chrome://flags#view-transition-on-navigation

Then add this meta element to the head of your website:

<meta name="view-transition" content="same-origin">

You could stop there. If you navigate around your site, you’ll see that the navigations now fade in and out nicely from one page to another.

But the real power comes with transitioning page elements. Basically, you want to say “this element on this page should morph into that element on that page.” And when I say morph, I mean morph. As Dave puts it:

Behind the scenes the browser is rasterizing (read: making an image of) the before and after states of the DOM elements you’re transitioning. The browser figures out the differences between those two snapshots and tweens between them similar to Apple Keynote’s “Magic Morph” feature, the liquid metal T-1000 from Terminator 2: Judgement Day, or the 1980s cartoon series Turbo Teen.

If those references are lost on you, how about the popular kids book series Animorphs?

Some classic examples would be:

  • A thumbnail of a video on one page morphs into the full-size video on the next page.
  • A headline and snippet of an article on one page morphs into the full article on the next page.

I’ve added view transitions to The Session. Where I’ve got index pages with lists of titles, each title morphs into the heading on the next page.

Again, Dave’s post was really useful here. Each transition needs a unique name, so I used Dave’s trick of naming each transition with the ID of the individual item being linked to.

In the recordings section, for example, there might be a link like this on the index page:

<a href="/recordings/7812" style="view-transition-name: recording-7812">The Banks Of The Moy</a>

Which, if you click on it, takes you to the page with this heading:

<h1><span style="view-transition-name: recording-7812">The Banks Of The Moy</span></h1>

Why the span? Well, like Dave, I noticed some weird tweening happening between block and inline elements. Dave solved the problem with width: fit-content on the block-level element. I just stuck in an extra inline element.

Anyway, the important thing is that the name of the view transition matches: recording-7812.

I also added a view transition to pages that have maps. The position of the map might change from page to page. Now there’s a nice little animation as you move from one page with a map to another page with a map.

thesession.org View Transitions

That’s all good, but I found myself wishing that I could just have those enhancements. Every single navigation on the site was triggering a fade in and out—the default animation. I wondered if there was a way to switch off the default fading.

There is! That default animation is happening on a view transition named root. You can get rid of it with this snippet of CSS:

::view-transition-image-pair(root) {
  isolation: auto;
}
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
  display: block;
}

Voila! Now only the view transitions that you name yourself will get applied.

You can adjust the timing, the easing, and the animation properites of your view transitions. Personally, I was happy with the default morph.

In fact, that’s one of the things I like about this API. It’s another good example of declarative design. I say what I want to happen, but I don’t need to specify the details. I’ll let the browser figure all that out.

That’s what’s got me so excited about this API. Yes, it’s powerful. But just as important, it’s got a very low barrier to entry.

Chris has gathered a bunch of examples together in his post Early Days Examples of View Transitions. Have a look around to get some ideas.

If you like what you see, I highly encourage you to add view transitions to your website now.

“But wait,” I hear you cry, “this isn’t supported in any public-facing browser yet!”

To which, I respond “So what?” It’s a perfect example of progressive enhancement. Adding one meta element and a smidgen of CSS will do absolutely no harm to your website. And while no-one will see your lovely view transitions yet, once browsers do start shipping with support for the API, your site will automatically get better.

Your website will be enhanced. Progressively.

Update: Simon Pieters quite rightly warns against adding view transitions to live sites before the API is done:

in general, using features before they ship in a browser isn’t a great idea since it can poison the feature with legacy content that might break when the feature is enabled. This has happened several times and renames or so were needed.

Good point. I must temper my excitement with pragmatism. Let me amend my advice:

I highly encourage you to experiment with view transitions on your website now.

Responses

Nicolas Hoizey

@davatron5000 @adactio do you know how we can target non-root elements in CSS to change the animation, if they are all like `view-transition-name: recording-7812` ?

I couldn’t make it work with `::view-transition-old(recording-*)` or `::view-transition-old(^=recording-)` for example…

Dave Rupert

@nhoizey @adactio I don’t think that’s possible yet because all transition names need to be unique. You could try generating a CSS block per recording/post in your loop? And do it on the post template? That’s my only idea for now.

Simon Pieters

@adactio “Are you the kind of person who flips feature flags on in nightly builds to test new APIs?”

Yes 😀

Simon Pieters

@adactio in general, using features before they ship in a browser isn’t a great idea since it can poison the feature with legacy content that might break when the feature is enabled. This has happened several times and renames or so were needed.

danielpietzsch.com

Prompted by Jeremy’s post on the topic, I’ve been trying out the brand new view transitions API for multi page apps – i.e. normal websites.

For the technical details, have a look at the linked article and the links therein.

So far, I have been trying it out on this site and on the photo journal. I only kept them on this site.

Currently using Chrome (standard v113 and Canary v115) on my 2018 MacBook Pro, it’s not really performing all that well, resulting in some stuttery and thereby distracting UI shifts. And it makes page transitions slower than they need to be.

This site

I found the standard cross-fade transition to be kind of too much and disabled it with the snippet Jeremy also mentions in his post. But I kept all the custom transitions I experimented with on this site with so far. This is mainly the animated move of the titles and dates from an index page to a permalink page. For videos, movies, and music, I also added transitions for the posters. And that is where this new API is at its most useful and impressive. Especially if it is performing properly – which I myself can’t really experience in full frame rate at the moment. I imagine the transition from the “Media” page to one of its subpages (“Movies”, “Music”, or “Books”) to be particularly impressive, with all those posters flying across the page – but, this does not look smooth at all on my machine.

Anyway, I am keeping those transitions for now. If you want to try it out, enable the chrome://flags “viewTransition API” and “viewTransition API for navigations” and browse this site yourself.

The photo journal

I also tried it with the photo journal, but ended up removing it again. It was just not all that useful or necessary – neither the full-page cross fade, not custom transitions of post titles. And again, slowing page transitions down unnecessarily.

While experimenting, I thought that a bit of animation would be nice, though. So what I did instead, was adding some plain CSS fade-in animation to the <img> elements on post pages and <li> elements on the overview. This eases the hard change from one page to another, is more subtle than with this new transitions API, and it can be seen in any browser right now.

Verdict

I will certainly have a closer and more serious look at this when performance improves and more browsers implement this. And I’ll probably experiment a little more in the meantime. Anyway, it is great, this API exists now! I bet this can make a lot of things easier and we can also get back to building more multi-page apps. ‘Cause my hot take is that a lot of the time, the main reason for a single page app is that people simply can’t stand a full page transition. And this API will eliminate that “problem” with a simple one-line meta tag.

# Thursday, May 25th, 2023 at 1:32pm

Silv

@adactio Oho, super exciting! The View Transitions API could allow all of the yummy goodness of smooth SPA animations on MPAs which I much prefer. Exciting stuff, thanks for sharing!

# Posted by Silv on Sunday, May 28th, 2023 at 11:30pm

13 Shares

# Shared by Nicolas Hoizey on Wednesday, May 24th, 2023 at 4:12pm

# Shared by Kat Moss on Wednesday, May 24th, 2023 at 4:12pm

# Shared by Chris Taylor on Wednesday, May 24th, 2023 at 5:03pm

# Shared by Zach Leatherman on Wednesday, May 24th, 2023 at 5:03pm

# Shared by Dave Rupert on Wednesday, May 24th, 2023 at 5:03pm

# Shared by mrtnvh on Wednesday, May 24th, 2023 at 7:30pm

# Shared by Eduard Dopler on Wednesday, May 24th, 2023 at 7:30pm

# Shared by Bruce B Anderson on Wednesday, May 24th, 2023 at 8:56pm

# Shared by Hyeonseok Shin 🤔 on Thursday, May 25th, 2023 at 1:07am

# Shared by Graham Harper on Saturday, May 27th, 2023 at 6:15am

# Shared by Ayo Ayco on Sunday, May 28th, 2023 at 5:37pm

# Shared by Silv on Sunday, May 28th, 2023 at 11:34pm

# Shared by Ade Oshineye on Monday, May 29th, 2023 at 7:58am

25 Likes

# Liked by Chris Jones on Wednesday, May 24th, 2023 at 3:25pm

# Liked by Nicolas Hoizey on Wednesday, May 24th, 2023 at 4:12pm

# Liked by Luke Dorny :ComputerClassic: on Wednesday, May 24th, 2023 at 4:12pm

# Liked by Pete on Wednesday, May 24th, 2023 at 4:37pm

# Liked by Dave Rupert on Wednesday, May 24th, 2023 at 4:37pm

# Liked by Chris Taylor on Wednesday, May 24th, 2023 at 5:03pm

# Liked by Zach Leatherman on Wednesday, May 24th, 2023 at 5:03pm

# Liked by Stefan Krieger on Wednesday, May 24th, 2023 at 6:01pm

# Liked by evenreven@ruby.social on Wednesday, May 24th, 2023 at 6:34pm

# Liked by Eric Wallace on Wednesday, May 24th, 2023 at 6:58pm

# Liked by patrickhaug on Wednesday, May 24th, 2023 at 8:56pm

# Liked by Luke Lau on Thursday, May 25th, 2023 at 1:07am

# Liked by Lewis Cowles on Thursday, May 25th, 2023 at 2:15am

# Liked by Yann Prono on Thursday, May 25th, 2023 at 6:19am

# Liked by Luca Fabbri on Thursday, May 25th, 2023 at 7:23am

# Liked by Dan Danowski on Thursday, May 25th, 2023 at 7:59am

# Liked by Simon Pieters on Thursday, May 25th, 2023 at 10:48am

# Liked by @reiver ⊼ (Charles) :batman: on Thursday, May 25th, 2023 at 2:13pm

# Liked by Adam Perfect on Thursday, May 25th, 2023 at 6:38pm

# Liked by Pelle Wessman on Thursday, May 25th, 2023 at 10:00pm

# Liked by Graham Harper on Saturday, May 27th, 2023 at 6:16am

# Liked by Murtuzaali Surti ✨ on Sunday, May 28th, 2023 at 7:19am

# Liked by Ayo Ayco on Sunday, May 28th, 2023 at 5:37pm

# Liked by Silv on Sunday, May 28th, 2023 at 11:34pm

# Liked by James :opensource: on Monday, May 29th, 2023 at 9:01am

1 Bookmark

# Bookmarked by https://dominikschwind.com/ on Wednesday, May 24th, 2023 at 3:53pm

Related posts

Browser support

Here’s Clearleft’s approach to browser support. You can use it too (it’s CC-licensed).

Displaying HTML web components

You might want to use `display: contents` …maybe.

Upgrades and polyfills

Apple’s policy of locking browser updates to operating system updates is bad for the web and bad for the planet.

Continuous partial browser support

Treat every browser feature like an experimental feature.

The Web Share API in Safari on iOS

Unexpected behaviour in the clipboard.

Related links

Tagged with

12 Modern CSS One-Line Upgrades | Modern CSS Solutions

I love how straightforward these bits of CSS are—time to rip out some of those old complicated hacks and workarounds!

Tagged with

Stop supporting Internet Explorer!

The headline is clickbaity, but the advice is solid. Use progressive enhancement and don’t worry about polyfilling.

When I say ‘Stop supporting IE’ it means to me that I won’t go the extra mile to get unsupported features working in Internet Explorer, but still make sure Internet Explorer users get the basics, and can use the site.

Tagged with

How we think about browsers | The GitHub Blog

JavaScript doesn’t get executed on very old browsers when native syntax for new language features is encountered. However, thanks to GitHub being built following the principle of progressive enhancement, users of older browsers still get to interact with basic features of GitHub, while users with more capable browsers get a faster experience.

That’s the way to do it!

Concepts like progressive enhancement allow us to deliver the best experience possible to the majority of customers, while delivering a useful experience to those using older browsers.

Read on for the nitty-gritty details…

Tagged with

Be the browser’s mentor, not its micromanager. - Build Excellent Websites

This one-page site that Andy has made to illustrate his talk at All Day Hey is exactly what I was talking about with declarative design.

Give the browser some solid rules and hints, then let it make the right decisions for the people that visit it, based on their device, connection quality and capabilities. This is how they will get a genuinely great user experience, rather than a fragmented, broken one.

Tagged with

Previously on this day

2 years ago I wrote Pace layers and design principles

I suppose it was inevitable that I would smush these two things together.

2 years ago I wrote The complete line-up for UX London

Emma Parnell, Videha Sharma, Amir Ansari, John Bevan, Alastair Somerville and Trenton Moss complete the roster.

7 years ago I wrote A workshop on evaluating technology

A framework for choosing your web toolkit.

8 years ago I wrote Regressive Web Apps

Killing the web to save it.

9 years ago I wrote 100 words 063

Day sixty three.

13 years ago I wrote Topically hot

Am I hot topic or not? I want your suggestions for this year’s @media.

13 years ago I wrote The good new days

Everything new is old again.

17 years ago I wrote South Parking

In which I spend a day in the epicentre of geekdom.

18 years ago I wrote That syncing feeling

I’ve been getting my emails, contacts and calendars in order.

21 years ago I wrote Cameras are kryptonite to Starbucks

I had no idea when this picture was taken that I was opening myself up to a potential tirade from a Starbucks manager. Lawrence Lessig has the story: