CSS view-transition: Scroll Navigation with Automatic Animations

Video thumbnail

We can add a smooth transition between each page, such as between the list view and the detail view, which is what we have here. This helps make the change less aggressive or abrupt, but much more fluid and visually pleasing.

To achieve this, we can use the view-transition API in CSS, which allows us to implement smooth transitions between pages. With this tool, we could also add animations so that the content appears from the side, from below, with scaling, or other visual effects.

All we need to do is add the following to our CSS stylesheet:

@view-transition {
 navigation: auto;
}

And that's pretty much it. With just these lines, we already achieve a smoother visual transition between pages.

Compatibility and support

Support is quite broad. Virtually all modern browsers support it, so we can use it without any problems. If the browser doesn't support this property, simply ignore it and browsing will continue to work as before, without errors or interruptions:

https://developer.mozilla.org/en-US/docs/Web/CSS/::view-transition

Once applied, you'll notice that the transitions between views now have a smooth fade or blur effect. We'll explain this more in the next lesson, but for now, you can see that the change isn't as abrupt as before, which is exactly what we were looking for.

Video thumbnail

Can you imagine being able to animate view changes between pages or sections without using external frameworks or libraries?
With View-transition in CSS, that's now possible. This new browser API allows for creating smooth transitions between document states, natively and controlled only with CSS (and optionally some JavaScript).

In this article, I'll show you how it works, how it compares to the classic scroll-behavior: smooth, and how you can apply it today to improve your users' visual experience.

I'm going to show you how you can make internal navigation animated in an HTML document with just one line of CSS code.

Let's remember the basics: we have a link that points to a heading identifier:

<a href="#heading-0" class="block text-lg mt-0 mb-0 text-blue-600 hover:underline ">
view-transition </a>
<h2 id="heading-0">view-transition </h2>

As we know, an identifier must always be unique on the HTML page.

What is view-transition and what is it for?

View-transition is a technology that allows animating the visual change between two DOM states—for example, when navigating between pages or dynamically modifying content.

Until recently, achieving something like this required JavaScript, opacity or transform, or even an SPA (Single Page Application) framework.
Now, thanks to the View Transition API, the browser automatically manages the captures before and after a change, and animates them using CSS.

When I started experimenting with smooth animations using scroll-behavior, I noticed that the jump to view-transition was the natural step: the same fluidity, but with total control over the views.

How do we make navigation animated using CSS and the @view-transition rule?

The magic begins with the @view-transition rule in CSS.
It defines how the visual transition behaves when a view change occurs.

html {
  scroll-behavior: smooth;
}

By applying it to the HTML document, navigation automatically becomes animated. It's that simple. With that, every time you clicked a link with href="#section", the page would smoothly slide to the destination. It's that simple.

Alternative with JavaScript

We can also do it very easily with JavaScript.
In the viewer on my academy website, when I click on a link, the same logic is executed: the scroll is automatically performed in an animated way:

document .querySelector(".YourElement")
.scrollIntoView({ behavior: "smooth", block: "center" });

Compatibility and Limitations

Like all new technology, @view-transition still has partial support; to check compatibility, we have:

if (document.startViewTransition) {
 // Usa la API nativa
} else {
 // Fallback con animación manual
}

For this, the scrollIntoView method is used on an HTML element.
You can check the parameters online, but basically, they serve to make the animation smooth and position the viewer in the middle.

Another alternative is to apply it globally on the window object, instead of associating it with a specific element:

  window.scroll({
    top: 0,
    behavior: "smooth",
  });

view-transition-name: The New Way to Make CSS Transitions Between Pages and Images

view-transition-name: The New Way to Make CSS Transitions Between Pages and Images
Video thumbnail

Here we have another very interesting API that reminds me a lot of the Hero effect we have in Flutter, which, for example, we can apply to images. Personally, I think this is where it's most noticeable, but you can actually use it with any element.

We have an image in the list view, and when you click on it, you can see it performs a smooth scaling animation for the detail page. It's important to note that IT MUST BE THE SAME IMAGE. It's not abrupt, as is often the default in web applications, but much more fluid and natural.

The API: view-transition-name

For this, we use the view-transition API, specifically the view-transition-name property. This property defines a unique name that will be used to link the same element in different views, for example, from the list to the detail view.

In the list view (index), we assign the corresponding name:

<img class="post" *** src="image1.png" style="view-transition-name: {{ $b->slug }}">

In the detail view, we do exactly the same thing.

<img class="post" *** src="image1.png" style="view-transition-name: {{ $book->slug }}">

The above implementation is from a Laravel project, but you can replicate it in other technologies like Django and with other fields like id…

It's key that the name is identical in both views. If we change it even slightly, as in the example with a different value, the animation won't apply and the change will be abrupt again.

Restrictions on names

Keep in mind that you can't use spaces or special characters (such as periods, quotes, etc.). Therefore, it's not recommended to use a filename or path directly. Instead, it's best to use the slug or a clean variable, similar to how variables are named in JavaScript or CSS.

Applying the view-transition-name to other elements

Although we're using an image here, you can apply this animation to any HTML element. In other examples, it could be a <header>, a button, or any content block.

Compatibility and support

Browser support is quite good. If the browser doesn't support it, it simply ignores it—just like the @view-transition property above—and the behavior will be the default (no animation). No problem:

https://developer.mozilla.org/en-US/docs/Web/CSS/view-transition-name

The only thing I'm not entirely convinced about is that you have to define the view-transition-name directly in the HTML, which can make the markup a bit messy. Still, it's worth it for how easy it is to use and for the elegant visual effect we achieve.

In short: good, simple, compatible, and with great results.

Conclusion

The arrival of the View Transition API marks a before and after in how we animate the web.
It's no longer just about moving elements, but about creating visual continuity between states, something we previously only saw in native apps.

In my case, moving from scroll-behavior: smooth to view-transition was like leveling up: more control, more fluidity, and the same simplicity.

It's that simple, but with professional results.

Frequently Asked Questions (FAQs)

  • What is the difference between View Transition API and scroll-behavior?
    scroll-behavior only animates the viewport scroll, while view-transition animates the complete content change.
  • Does it work on all HTML pages?
    Yes, as long as the pages belong to the same domain (origin).
  • Can I combine it with frameworks like React or Vue?
    Yes, and in fact, it's a great option for SPAs. You just need to control the renders and call startViewTransition() when changing routes.
  • What happens if the browser doesn't support it?
    Nothing serious: the content is displayed immediately, without a transition.

I agree to receive announcements of interest about this Blog.

You will learn how to use @view-transition { navigation: auto } in CSS, one of the new properties that allows you to create smooth transitions between pages without the need for JavaScript. You will also learn about Page Effects and images with view-transition-name: Magic CSS without JS in the style of Hero in Flutter.

| 👤 Andrés Cruz

🇪🇸 En español