DEV Community

Emmanuel Elikwu
Emmanuel Elikwu

Posted on

Your HTML Pages Can Animate Like This Now! (No JavaScript Required)

When navigating between HTML pages on traditional multi-page applications (MPAs), the browser reloads the page, causing an abrupt white flash or jump. For years, achieving fluid transitions meant building a Single Page Application (SPA) with React, Vue, or heavy client-side routing libraries.

That is no longer required. Modern browsers now support Native Cross-Document View Transitions, allowing smooth animations between separate, real HTML files using pure CSS.

In this tutorial, we will turn a multi-page luxury automotive site (Orion Motors) into an app-like experience with zero custom JavaScript.


1. The Core Rule: @view-transition

To allow separate HTML documents to participate in a cross-document view transition, both the outgoing and incoming pages must opt in.

If all your HTML pages share a single stylesheet (e.g., styles.css), you only need to write this single rule:

@view-transition {
  navigation: auto;
}
Enter fullscreen mode Exit fullscreen mode

Note: This rule enables native cross-document transitions for eligible, same-origin navigations.


2. Customizing Global Page Transitions

When a view transition occurs, the browser creates temporary pseudo-elements representing the outgoing state (::view-transition-old(root)) and the incoming state (::view-transition-new(root)).

We can apply custom keyframe animations to these pseudo-elements to control our exit and entry effects:

/* Target the outgoing page */
::view-transition-old(root) {
  animation: 0.36s ease-in pageOut;
}

/* Target the incoming page */
::view-transition-new(root) {
  animation: 0.48s cubic-bezier(0.22, 1, 0.36, 1) pageIn;
}

/* Keyframe Animations */
@keyframes pageOut {
  to {
    opacity: 0;
    filter: blur(4px);
    transform: scale(0.98);
  }
}

@keyframes pageIn {
  from {
    opacity: 0;
    filter: blur(4px);
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    filter: blur(0);
    transform: translateY(0);
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Shared Element Transitions with view-transition-name

Animating whole pages is great, but modern app UI relies on shared elements—like an image on a product card morphing smoothly into the main hero image of a detail page.

To achieve this:

  1. Give the element on Page A and the corresponding element on Page B the exact same view-transition-name.
  2. Ensure each name is unique per rendered page.
/* Orion V12 Car Model */
.car-v12 {
  view-transition-name: orion-v12;
}

/* Orion S9 Car Model */
.car-s9 {
  view-transition-name: orion-s9;
}

/* Orion E7 Car Model */
.car-e7 {
  view-transition-name: orion-e7;
}
Enter fullscreen mode Exit fullscreen mode

Refining Movement with ::view-transition-group

You can target the container managing the named transition (::view-transition-group) to customize timing, curves, and physics:

::view-transition-group(orion-v12),
::view-transition-group(orion-s9),
::view-transition-group(orion-e7) {
  animation-duration: 0.72s;
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  • @view-transition { navigation: auto; } enables native cross-document transitions across separate same-origin HTML files.
  • Use ::view-transition-old(root) and ::view-transition-new(root) to customize whole-page exit and entry styles.
  • Assign identical view-transition-name values to elements across pages to seamlessly morph images, headings, and cards.
  • Keep your architecture clean, fast, and accessible without shipping heavy client-side JavaScript routers.

Take Your CSS to the Next Level 🚀

If you want to build clean, responsive layouts like a senior developer even faster, I packaged these architectural patterns into a practical resource:

👉 Grab the Guide: Build Any Responsive Layout with CSS Grid & Flexbox

It is designed to take you from layout confusion to confidently building any complex layout you see online!


Resources

🎥 Watch the Complete Step-by-Step Tutorial: YouTube Video Walkthrough

Top comments (0)