Chrome Page Transitions in Modern Frontend Frameworks
With Google IO a few days ago, all sorts of new and interesting things got announced. One thing that really struck my imagination was the new Google page transitions functionallity for web. I wanted to take a look at the new API and see how difficult it would be to implement in a site like mine.
The Google team posted a video explaining the new API, as well as a demo and github repo showing us how it works so I have a nice jumping off point, but to put it simply, the Page Transition API allows developers to define transitions between states on Single Page Apps (and in future standard websites), much like you would experience on an android/iphone app. For example, looking at the demo Google provided, we can see how the video pops out of the image on the index page, before the related videos slide in from the right.
Unfortunately, this feature is still in active development. So we're going to have to install the chrome canary build (basically their dev branch) in order to preview it. If you're developing on mac like I am, you can do this with the following brew command, or you can install it the old fashioned way here.
Once that's installed, we need to enable the following feature flags to enable Page Transitions. This feature isn't really "released" just yet, even in the canary build, so these flags tell chrome that we want to preview this less stable feature.
- Experimental Web Platform features
- documentTransition API
If you've never enabled a flag in chrome before, it's quite simple. We go to chrome://flags/ and use the search to enable/disable the ones we want.
Once that's enabled, if you go back to their demo, it should now work for you.
Wait this didn't exist before?
You might be forgiven for thinking that some sites already had this functionality. And in some cases you would be almost right. For single page apps, there are variety of page transition libraries. Notably Svelte Transitions and React Transition Group.
While these transition libraries do offer basic transitions such as fade out and fade in, to transition elements that aren't already in the correct place for the new page would require pulling items out of the DOM, figuring out the movement path with JS, would likely cause havoc for reactivity, and wouldn't be worth the effort in most cases. True Cross Fades have also been completely impossible until this API.
Using this functionality in svelte
This site is written in sveltekit which, much like Nuxt or Quasar, is a frontend web app framwork written around reactive web framework (In this case svelte, with Nuxt being the equivilent for VueJs). Sveltekit, much like other app frameworks, takes care of routing for you. While this means you can create links using standard a tags, once again the current limitations of the page transition api, mean that we need to call a function.
In sveltekit, we have access to a function called
goto which triggers the router to redraw the DOM with the contents of a new page and update the browser history accordingly. We can import that from the navigation helpers in svelte.
Let's wrap our function around that. we can create this new function with the name
transGoTo using camelCase properly.
Typescript might complain at this point that
createDocumentTransition does not exist on the type
Document. You can safely ignore this. Once the api is more stable and better supported, typescript interfaces will be updated. That being said, I wouldn't use this on anything in a production environment. Especially not if you're uncomfortable doing a lot of tweaks as the API is changed, just so that a few devs that have the flags enabled can see your flashy animations. It may also never get wide support outside of chrome. Most browsers are based on chromium now though so I don't worry about that last one too much.
To use this instead of a link, we just need to import our function into our svelte component and then add an onclick action wherever we want the link. You shouldn't need to remove the href and I'd probably recomend keeping it in the event users have JS disabled. We might need to add
event.preventDefault() if the link still navigates as it used to though.
With that, we should now have basic coss-fade transitions, as you can see below, it works quite well on the blog listing page.
Extending past the basic fade
As stated earlier,
svelte/animations and the like already include simple fade in/out transitions. Before you add custom transitions with the transition api, you'll want to disable the fade transition with the following CSS by referencing the psudo elements used for transitions.
You will also want to bring the outgoing image to the front, at least initially. so you can move it about.
You may notice that these selectors reference an image. This is due to the way in which the api works. It essentially takes an image of the screen, waits for the new screen and takes an image of that too, then it transitions between the images in front of the actual updated DOM.
We can label DOM elements with transition tags in the CSS, so that the transitions know to treat them as a seperate image. If two elements have the same tag, this will trigger them to move to the correct location and size as part of the transition.
If two elements have the same transition tag, the transition api will treat them as the same element even if they have different tags. That's how the image turns into a video in the official demo. On the outgoing page, the clicked
img tag, has the same tag as the video
To add a custom animation, you can use css keyframe animations. Just select the outgoing/incoming image for the element-tag that you want to animate and apply the animation as you would anywhere else in your css.
It can require a bit of tweaking to make animations look right as transitions but nothing that you wouldn't do if you were putting a transition elsewhere.
Overall, I think this is a really cool new API that will help bridge the gap between native and web based experiences, especially in the realm of PWAs. It still needs a bit of work before it's ready for primetime. I encountered a couple of bugs here but that's to be expected. Many of the default native app animations that you would have on mobile also aren't currently aren't available unless you create them yourself but there are sure to be libraries of animations that will be created for the API as time goes on.
I can't wait to see page transitions more frequently on web, they're going to improve the experience a lot... assuming that people don't start using those star wipe transitions that teachers always used to use in powerpoint... In the meantime, I'll be shelving the branch of this sites code with the transitions on. As much as I'd love to be a super early adopter, I'll probably wait till it makes it out of canary.