 It is important for a user interface to feel polished and fluid. A great way to help with that are appropriate animations. They help users build an accurate mental model of how the interface works, thereby increasing the overall usability. Shipping in Chrome is a collection of new web APIs that you achieve exactly that. My name is Brahmius, and let's take a look at what's new in web animations. At last year's I.O., Jake Archibald talked about page transitions, an API that makes it easy to change the DOM in a single step while creating an animated transition in between the two states. Back then, it was just an experiment behind a feature flag in Chrome Canary. But now, thanks to your feedback, that experiment was developed into a full feature within the CSS Working Group. It's now called View Transitions, and single-page application support shipped in Chrome 111. To use View Transitions, take your code that updates a DOM by whatever method, and wrap it in the View Transition API with a fallback for browsers that don't support the feature. And just like that, you get a crossfade between the two states. This animation happens in a tree of pseudo elements, meaning you can customize it with CSS. The small chunk of code like this changes the default to a fade-in slide. You can use code like this, which gives you this popular sci-fi wipe effect. Don't worry about reading all the code now. I just want to show you it's a small chunk of code. If you want to take a closer look, all of the demos are linked in the description. You can even create some truly silly effects like 3D spins, or slams, or whatever you want. In all of these examples, the whole page is transitioning together, but you can also transition parts of the page independently. You can do this by giving an element a ViewTransitionName. Now it's captured separately from the rest of the page, meaning you can animate it independently. Take this example, where thumbnails zoom into the full image and the header stays fixed in place. This is all possible today in Chrome, and you can use it as a progressive enhancement so it doesn't disrupt other browsers. We have a full guide to the feature if you want to get started, including how to use these ViewTransitions alongside frameworks like React, View, Svelte, and Lit. We've already seen a number of companies using ViewTransitions to enhance their sites today. Some have already shipped, and some are still in development. One implementation I really like is this wonderful demo by Maxi Ferrera. Leveraging ViewTransitions, this demo app is enriched with tasteful and supporting transitions between the two types of views. What I love about this demo is that it shows you that interactive elements like the video keep playing while the ViewTransition is happening. And this real demo from Airbnb which shows the kind of rich transitions that you can create between states even though the state is changing synchronously in the background. But that's not the end of the story for ViewTransitions. There are more extra features and enhancement we want to add. For example, check out this demo. It doesn't look much different to some of the demos from earlier, but this page has no JavaScript, a total lack of JavaScript, zero bytes on the JavaScript scale. This is because it isn't an SPA, it's just plain old links between multiple pages, but with ViewTransitions in between them. This demo works today in Chrome Canary with the ViewTransitionalNavigationFeature flag set to enable. It works pretty much the same as the SPA API, but rather than using script to tell the browser about the DOM change, the browser can do that itself with a page change because it's already in charge of navigations. It already knows when it's switching from one page to another. The CSS to customize the transition is the same as it's the same set of pseudo elements. It even works well with other navigation enhancing features like pre-render, which reduces the time between the user clicking a link and the transition starting. We have work to do before this gets too stable, particularly when it comes to how two pages opt into a ViewTransition, but we're actively working on it. Let's rewind a bit and go back to the world of SPA transitions. Right now only one ViewTransition can happen at a time, and that's a bit of a problem. If you try and start a new transition while one is already running, the old one skips to the end so the new one can start. But what if, instead of document.startViewTransition, you could do element.startViewTransition. That way, two components, such as the video player or chat widget, could perform ViewTransitions, scope to their element and run independently. Here we're exploring and we're calling it ScopedTransitions. One more feature we're exploring. Right now you can create ViewTransition where the page header animates independently from the rest of the page. This works great when a header is in the same position on both pages, but that isn't always the case. Sometimes one of the pages will have scrolled potentially thousands of pixels. That means, by default, the header will animate from thousands of pixels away so most of its animation will be out of view. That generally isn't what you want in terms of visual effect. To solve this, we're exploring ideas around some kind of opt-in that, as you say, here's my header. It should animate independently in the ViewTransition. But if it isn't in the ViewPort, just pretend it isn't there. And that's just a few of our thoughts. See the description for our link to more future ideas and let us know which one you're most excited about in the comments. Now, let's take a look at some of the more driven animations. A very exciting addition that allows you to control the playhead of an animation by the scroll position of a scroll container. This means that as you scroll up or down, an animation will scrub forward or backward. Take this progress bar at the top of the page, for example. As I scroll up and down through the page, the progress bar also gets adjusted. Now, the cool part about this is that this demo is powered by more exciting. The animation itself runs on the compositor. Yeah, you heard it right. Now, the single line of JavaScript was used to build this and it's not blocking the main thread in any way. This doesn't mean you can't use JavaScript at all for this. On the contrary, if you want, you can. That's because this new API also comes with a set of JavaScript classes that integrate nicely with the Web Animations API. For this talk, however, I'm focusing on the CSS approach. So, back to the example. Let's look at some code. To grow the progress bar, I have a set of keyframes that scale it up on the x-axis. These keyframes are attached to the progress bar using the animation property. Nothing new there. However, instead of letting the animation run on page load, I attach it to a scroll progress timeline using the animation timeline property. Its value is set to scroll block root, which tells the browser to track the scroll progress of the root scroller, the document scroller, on the block axis and map its progress to the animation progress. Furthermore, because seconds no longer have any meaning here, I set the animation duration to auto. And with just that little piece of code, you get the result I've already shown you. I scroll down the page, the animation progresses. That's pretty neat, right? The scroller to track doesn't need to be the root scroller, by the way. To target a different scroller, change the scroller argument that gets passed into the scroll function. Accepted values are self to track the box's own scroll progress, nearest to track the progress of the nearest parent element that is also a scroller, or root, which I've already shown. The default value is nearest. To change which axis to track, alter the axis argument to the function. Accepted values are horizontal and vertical, in line and block keywords, the default being block. As both the scroller and axis arguments have a default value, you can opt to only declare one, or simply omit both of them. In this slide, both code examples are equivalent as a both target the same default values. With the scroll function I've just shown you, you create an anonymous scroll timeline. To refer to a specific scroller when that's not the nearest scrolling parent or root, you can create a named scroll timeline. For this, use the scroll timeline name property and set its value to an identifier of your choice. Optionally, you can also set the scroll timeline axis to define which axis to track. On the element that needs to animate, you then use that scroll timeline name as the value for the animation timeline property. One side note with using named progress timelines in CSS is that the scroller currently must be a parent element of the animated element. We're looking into ways to relax this restriction, but for now we'll just have to keep it in mind. If you're already excited about this, create. If not, maybe the second part this feature offers can lure you in. Because with scroll driven animation, you can also drive an animation based on the position of an element within its scroll container. This is somewhat similar to how Intersection Observer works. Here's an example where the images fade in as they enter the scroll port. And again, this is all on using just CSS. It's a regular faded animation, but it's attached to a view progress timeline that tracks the image within its scroller. To create a view progress timeline, set the animation timeline property to view. By default, an animation linked to the view progress timeline attaches to the entire range of it. This range starts from the moment the subject enters the scroll port and ends when the subject has left the scroll port. Using the animation range property, it is possible to bind the animation to a specific part of view progress timeline. Here it is set to entry, which tells the browser to run the animation from start to finish while the element is entering the scroll port. You can start and end an animation in different ranges or different positions within those ranges. In addition to the entry range, other allowed values are exit, cover and contain. There's also entry crossing and exit crossing. The tools shown on screen and linked in the description below can help you understand what each range means and how the specified percentages affect the start and end position. A different approach, but one that gives you more flexibility, is to adjust the keyframes themselves without specifying an animation range. As you can see in this snippet, the range information is included in the keyframes themselves. That way you can link up one set of keyframes that control the animation effect in all ranges. Here's a demo that uses the keyframes that were just shown on screen. The entries in the list animate in at the bottom during the entry phase and at the top they animate out during the exit phase. How cool is that? So, that was scroll driven animations. I'm very excited about it. There's a ton of things that you can do with it, such as creating parallax background effects, sections that move horizontally as you scroll down or even this album visualization that you can flick through. And yes, that demo too is powered by nothing but HTML and CSS. Now the single line of JavaScript is to be seen inside. If you want to learn more about it, visit developer.chrome.com for an in-depth article which includes all of the demos I've just shown you. In addition to the CSS approach, the article also covers the JavaScript approach. You can find the link in the description below, along with the link to a code lab to try it out yourself. On to the next part. Compared to the previous two features I just talked about, the next one might be pretty small in comparison. Nonetheless, it's one that will come in handy if you want to precisely control the easing curves of your animations. I'm talking about the linear easing function and it's available in Chrome 113 and Firefox 112. Now, don't let the name of the function fool you, because with it you can create complex easing functions in a very simple manner with the compromise of losing some precision. Let's take this bounce easing for example. The blue box is animated using it. It's really nice and smooth. Unfortunately, creating such an easing function is currently not possible in CSS, but here's the good news. What if you didn't need to? What if you could fake it? Well, that's where the linear easing function comes into play. It allows you to reduce a complex curve to a more simplified version. So let's take the original curve in blue and simplify it by adding some points or stops onto it. Here, each green dot indicates a stop. Then, and this is where the linear function gets its name from, the interpolation between each stop is done in a linear way. The result is a curve that kind of looks like the original, but it's a bit rougher on the edges. Compare the green animated box to the blue one. You can tell it's not as smooth. But, if you add enough stops, you can approximate the original curve quite well. Here's an updated version. By merely doubling the number of stops you already get a smooth result. The code looks like this. A function named linear that you can set as the value for the animation timing function property. The function accepts a list of stops and a stop can be a single number that ranges from 0 to 1. By default, these stops are spread equidicently, and for more finer control, you can specify the stop length as a percentage. To easily create these simplified curves, my colleagues Jake and Adam have built a tool to help you with this. The tool takes the JavaScript easing function or SVG curve as its input and out comes a simplified curve which uses linear. Pretty cool, right? Now we're finally able to have effects that bounce or have elastic easings all from it in CSS. Last but not least, let's look into individual transform properties, a feature that landed in Chrome 104 and that is available in all three main rendering engines. With individual transform properties you can more easily manipulate parts of a transform or animation. Take this example where a target element scale changes from 1.2 to 2 on hover. Because of how transforms work you now need to duplicate all individual transform functions for the property and also make sure that you list them in the same order. Now let's take a look at what we can do with this tool. This is a tool that developers prefer to be honest. With individual transform properties this is now solved as you have standalone properties for that. I'm talking about translate, rotate and scale. Here's the revised code. In the hover state we only change the value for the scale property without needing to repeat the others. That's easier, right? Even though the rotation in the example goes from 0 to 360 degrees over time I need to calculate the rotation for every keyframe where the scale transform also changes something. Here's the resulting keyframes for that timeline using the transform property. For the animation to run as I want I need to add the rotate transform function to every keyframe. This is quite tedious especially with multiple transforms at various points in time. Leveraging individual transform properties and updated code now looks like this. I think this is much easier to read as it more clearly expresses the intent behind it. Going further this also allows you to easily split up the keyframes per function and apply each set of keyframes individually to the element. This way you can more easily change your easing or duration per aspect that you want to animate. Before we close there's an important note I have to mention with this. The order in which these new properties with the regular transform the transformation functions get applied in the order they are written in that is from left to right. With individual transform properties this is not the case. The order is always the same. First translate then rotate and then scale. That means both of these code snippets here give the same result. Oh and finally if you mix these with the transform property is it transformed that gets applied and that's translate, rotate, scale and then transform. And with that we're already at the end of this session. I'm very excited to see all these new features available in Chrome as they help you build frictionless and engaging experiences. Even more features are on the way. So be sure to keep an eye on developer.chrome.com for updates. A huge thank you goes out to our engineering teams who not only implement these features in the rendering engine but also in the specifications and APIs in collaboration with the standards bodies while also incorporating feedback as their well-gathered from you. So what are you building? Leave a comment below or drop us a link on social media. Bye!