How to Configure Strict CSS View-Transition-Old and New Animation-Direction in Google Chrome

Modern web applications with complex motion design often need to reverse, alternate, or mirror transitions depending on whether a user is navigating forward or backward through a workflow. For instance, when stepping through an onboarding wizard or navigating between master-detail views, moving forward should cause the new screen to slide in from the right, while clicking “Back” should reverse the animation so the previous screen slides back in from the left. Rather than authoring separate duplicate keyframe sets for every directional permutation, developers can leverage animation-direction directly on the View Transition pseudo-elements.

Configuring strict animation-direction rules in Google Chrome allows developers to reuse singular keyframe definitions cleanly, dynamically toggling between normal, reverse, and alternate playback modes based on navigation intent.

Chromium View Transition Direction Architecture

When Chromium initiates a view transition, it creates the temporary pseudo-element image pair:

::view-transition
 └─ ::view-transition-group(content-viewport)
     └─ ::view-transition-image-pair(content-viewport)
         ├─ ::view-transition-old(content-viewport)
         └─ ::view-transition-new(content-viewport)

By default, both pseudo-elements run their associated CSS animations with animation-direction: normal. However, by detecting the navigation direction in JavaScript or using CSS attribute selectors on the root <html> element, developers can apply animation-direction: reverse to invert keyframe progression on demand:

/* Shared singular keyframe definition */
@keyframes slide-horizontal {
    from {
        transform: translateX(100%);
    }
    to {
        transform: translateX(0);
    }
}

/* Forward Navigation: New element slides in from right (normal) */
html[data-nav-direction="forward"]::view-transition-new(content-viewport) {
    animation-name: slide-horizontal;
    animation-direction: normal;
    animation-duration: 350ms;
}

/* Backward Navigation: Incoming element slides in from left (reverse) */
html[data-nav-direction="back"]::view-transition-new(content-viewport) {
    animation-name: slide-horizontal;
    animation-direction: reverse;
    animation-duration: 350ms;
}

Authoring Clean Bidirectional Keyframes

To avoid jarring jumps, ensure that animation-fill-mode: both is paired with animation-direction: reverse so that the reversed animation begins smoothly at the 100% keyframe state:

/* Exit slide animation */
@keyframes slide-exit {
    from {
        transform: translateX(0);
        opacity: 1;
    }
    to {
        transform: translateX(-100%);
        opacity: 0;
    }
}

/* Forward Exit: slides left */
html[data-nav-direction="forward"]::view-transition-old(content-viewport) {
    animation: 350ms cubic-bezier(0.2, 0, 0, 1) both slide-exit;
    animation-direction: normal;
}

/* Backward Exit: reverses and slides right */
html[data-nav-direction="back"]::view-transition-old(content-viewport) {
    animation: 350ms cubic-bezier(0.2, 0, 0, 1) both slide-exit;
    animation-direction: reverse;
}

Setting Navigation Direction via JavaScript

Set the data attribute on the document element before invoking document.startViewTransition():

async function navigate(targetUrl, direction = 'forward') {
    document.documentElement.dataset.navDirection = direction;

    if (!document.startViewTransition) {
        window.location.href = targetUrl;
        return;
    }

    const transition = document.startViewTransition(async () => {
        await updateDOM(targetUrl);
    });

    try {
        await transition.finished;
    } finally {
        delete document.documentElement.dataset.navDirection;
    }
}

Inspecting Directional Playback in Chrome DevTools

To verify that keyframe playback directions reverse properly:

  1. Open DevTools (F12) in Google Chrome and switch to the Animations tab via Ctrl+Shift+P > Show Animations.
  2. Trigger a “back” navigation state transition.
  3. DevTools captures the animation track. Inspect the timeline markers to confirm that keyframes interpolate in reverse order.
  4. Select ::view-transition-old and ::view-transition-new in the Elements tree and verify that animation-direction: reverse is computed accurately.

Configuring strict animation-direction controls eliminates redundant stylesheet code and produces seamless bidirectional navigation across Google Chrome.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.