View Transitions: The Smooth Parts Posted October 22, 2025 by Matthias Ott 29 Webmentions #blogtober #css #platform #View Transitions #web Now that cross-document view transitions are gradually making their way into modern browsers, now seems like the perfect time to explore them, if you haven’t already. They are, in fact, surprisingly straightforward to implement. And just like we’ve seen with modern images, view transitions can be slapped onto existing projects as a progressive enhancement. That my website is now called a “multi-page app” (MPA) is still a hilarious thought 😂, but hey – I’ll take it if I get a smoother experience with basically just one line of CSS: @view-transition { navigation: auto; } You add this @view-transition declaration to all pages of your site that should be transitioned – in my case I added it to the main.css – and every browser that supports cross-document view-transitions, will now fade between the (same-origin) pages. And: You can try it on this website already. 🥳 To see view transitions in action, click on “Home” or ”Articles” in the main navigation, for example. But please come back here after that! How It Works # The way cross-document view transitions work is that when you navigate to a new page, the browser starts loading it in the background and captures a snapshot. It then cross-fades from your current page snapshot (the old state) to the new one. But with one important detail: the page loading process remains incremental. The browser waits for the <head> to load before starting the transition animation, but then decides independently how much of the <body> to wait for. This can affect the actual user experience. First-time visitors or users on slower connections may not see transitions at all if the animation start before content has been loaded. Or, elements could still be loading while the animation is already running, leading to a weird and clunky experience. Repeat visitors with cached resources are more likely to see smooth transitions. But in practice, the experience can vary between navigations on the same device, depending on the connection speed, for example. Thanks to Martin Trapp for highlighting this. Martin runs a fantastic project, by the way – a bag of tricks, explainers, and demos around view transitions. Be sure to check that out. Waiting for Content to Load # What we can do to make the experience a bit smoother is to tell the browser which content to wait for before the animations can be started. For this, we use the new expect value for the rel attribute of the <link> tag and specify the element the browser should wait for by its ID. This could be your #main content, the #body, or any other important element – you decide. ... ... Also keep in mind that if #body or #main loads slowly – because of heavy images or a network fetch, for example – the transition may feel delayed or janky. So always test and consciously decide if this is a good solution in your specific case. Maybe this is also a good reason to improve the overall performance of your site? Respecting prefers-reduced-motion # Something that can make the whole experience more accessible is to respect the prefers-reduced-motion media query, so that people with motion sensitivity will not see the animation: @view-transition { navigation: auto; } @media (prefers-reduced-motion) { @view-transition { navigation: none; } } But: you should always consider whether this is actually necessary – which depends on the type of animation. It’s certain kinds of motion, or degrees of motion that can cause problems, not simply the presence of any animation. Simple fades between pages, for example, are generally seen as quite safe and less likely to trigger vestibular disorders. If you are using grow, scroll, or slide animations, however, better use prefers-reduced-motion to reduce or remove those motion-heavy transitions. A Few View Transition CSS Tricks # Now, once you start looking under the hood, things can become a bit more complicated. This post won’t go into all the details – we don’t have time for that – but I’ll highlight a few of the things that are really straightforward to implement and can further improve the experience with a few quick moves. Fine-tuning Animations # If you want to adjust the animation used for the transition, you will have to dig a bit deeper and use one (or more) of the many pseudo-elements, that are available once you activate view transitions for a page. As I mentioned, view transitions work by taking snapshots of the old and new states – of the root document and all named transition that have a view-transition-name. With those snapshots, the API then constructs an actual pseudo-element tree: ::view-transition └─ ::view-transition-group(root) └─ ::view-transition-image-pair(root) ├─ ::view-transition-old(root) └─ ::view-transition-new(root) The ::view-transition sits in an overlay over everything else on the page. The ::view-transition-group contains the image pair being used for the transition. The cool thing is: all the animations are now done using CSS animations. So you can use regular CSS to adjust the duration or the timing function, for instance: ::view-transition-group(root) { animation-duration: 600ms; animation-timing-function: cubic-bezier(0.3, 0, 0.8, 1); } Or, you can even define @keyframe animations and set the animations for the old and new state to completely individual animations. ::view-transition-old(root) { animation-name: dash-out; } ::view-transition-new(root) { animation-name: dash-in; } @keyframes dash-out { to { translate: 100% 0; opacity: 1; } } @keyframes dash-in { from { translate: -100% 0; opacity: 1; } } This is still a very basic example. But the ability to use standard CSS keyframe animations gives you plenty of flexibility to craft unique, tailored transitions for your specific use case. There’s also a lot more you can do to fine-tune animations, for example by using the JavaScript features of the View Transitions API and the pagereveal and pageswap events. Or defining your own transition types and then using different types to animate forwards and backwards between states. That’s a topic for another post, though. For now, I'll probably stick with a more basic implementation on this site. Progressive enhancement FTW! And in case you want to learn a bit more, watch Bramus and Kevin explaining view transitions in more detail: https://www.youtube.com/watch?v=quvE1uu1f_I ❦ This is post 20 of Blogtober 2025. ~ 28 Webmentions Jeff Bridgforth 23 October 2025 | 16:55 It might be helpful to link to the conversation Kevin had with Bramus when you mention it under a few other CSS tricks. I found that you linked to it at the end of the article but I had to look for it. Just a suggestion. Thanks for your thoughts on this subject. Very helpful. Matthias Ott 23 October 2025 | 17:07 Ah dang – I moved it to the bottom… 🤦♂️ 6 Reposts John Allsopp 23 October 2025 | 08:21 alcinnz 23 October 2025 | 08:22 Aaron T. Grogg 23 October 2025 | 08:22 Nilesh Prajapati 23 October 2025 | 11:26 KB 23 October 2025 | 17:08 Mike E 26 October 2025 | 11:08 21 Likes Sam 23 October 2025 | 08:21 goodreds 23 October 2025 | 08:22 Eric Portis 23 October 2025 | 08:22 Allan Kukral 23 October 2025 | 08:22 OpenGraph Tools 23 October 2025 | 08:22 Aaron T. Grogg 23 October 2025 | 08:22 Dom Jay 23 October 2025 | 08:22 Niels van Rongen 23 October 2025 | 08:22 Alexander Lehner 23 October 2025 | 08:28 Jordi Sánchez 23 October 2025 | 08:28 Nilesh Prajapati 23 October 2025 | 11:26 Erik Vorhes 23 October 2025 | 17:08 Jonas Pelzer 23 October 2025 | 17:08 Peter Grucza 23 October 2025 | 17:08 Martin Trapp 23 October 2025 | 17:08 Bag of Tricks for View Transitions 23 October 2025 | 17:08 DevStory 23 October 2025 | 17:08 Jeff Bridgforth 26 October 2025 | 11:08 Mike E 26 October 2025 | 11:08 Joe Crawford 26 October 2025 | 11:08 🪬🍄🌈🎮💻🚲🥓🎃💀🏴🛻🪕🧿 26 October 2025 | 11:08 ⓘ Webmentions are a way to notify other websites when you link to them, and to receive notifications when others link to you. Learn more about Webmentions. Have you published a response to this? Send me a webmention by letting me know the URL. Ping! More Notes Ad Infinitum Lazy and Prompt Buckle Up At Machine Speed
Jeff Bridgforth 23 October 2025 | 16:55 It might be helpful to link to the conversation Kevin had with Bramus when you mention it under a few other CSS tricks. I found that you linked to it at the end of the article but I had to look for it. Just a suggestion. Thanks for your thoughts on this subject. Very helpful.