::view-transition-old() CSS Pseudo Element
Description
The ::view-transition-old() pseudo-element represents the outgoing (old) visual state of an element during a View Transition, allowing developers to animate how content leaves the screen when the DOM changes. It is part of the CSS View Transitions API, which enables smooth, native-style transitions between UI states without relying on JavaScript-heavy animation logic. This pseudo-element is automatically generated by the browser during a transition and corresponds to a snapshot of the element before the update occurs.
During a view transition, the browser captures two renderings: the “old” state and the “new” state. The ::view-transition-old() pseudo-element targets the former - essentially a visual clone of the element as it existed prior to the change. This allows you to animate properties such as opacity, transform, or clipping to create effects like fading out, sliding away, or shrinking. It is typically paired with ::view-transition-new(), which represents the incoming state, allowing for coordinated animations between the two phases.
Unlike traditional pseudo-elements such as ::before or ::after, ::view-transition-old() does not exist in the DOM tree and cannot be inspected directly. Instead, it is a transient rendering layer managed by the browser during the transition lifecycle. You target it using the ::view-transition-old(name) syntax, where name corresponds to a value set using the view-transition-name property on an element. This mapping allows fine-grained control over which elements participate in the transition and how they animate.
A common use case is animating page-level or component-level transitions, such as switching tabs, navigating between views, or updating major UI sections. For example, when a container changes its contents dynamically, you can fade out the old content smoothly while fading in the new one, resulting in a polished and native-feeling experience. Because the transition is handled by the browser’s rendering engine, performance is typically better than JavaScript-driven animations.
Example: Fading out the old view
<div class="card" id="card">
<p>Old content</p>
</div>
<button onclick="updateContent()">Change Content</button>
.card {
view-transition-name: card;
}
/* Animate the outgoing state */
::view-transition-old(card) {
animation: fade-out 300ms ease forwards;
}
@keyframes fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
JavaScript
function updateContent() {
document.startViewTransition(() => {
document.getElementById("card").innerHTML = "<p>New content</p>";
});
}
In this example, the old content fades out smoothly before the new content appears. The browser automatically handles snapshotting and timing, while ::view-transition-old() controls how the outgoing visual state behaves.
Key characteristics
- Only exists during an active view transition
- Represents the pre-update visual state
- Can be animated using standard CSS animations
- Works in tandem with
::view-transition-new() - Requires
view-transition-nameto associate elements
Syntax
::view-transition-old([ <pt-name-selector> <pt-class-selector>? ] | <pt-class-selector>) {
/* ... */
}
Values
- <pt-name-selector>This is a developer-defined identifier (custom identifier) that corresponds to the CSS property view-transition-name set on the original DOM element.
Example
Browser Support
The following information will show you the current browser support for the CSS ::view-transition-old() pseudo element. Hover over a browser icon to see the version that first introduced support for this CSS psuedo element.
This psuedo element is supported by all modern browsers.
Desktop
Tablets & Mobile
Last updated by CSSPortal on: 31st December 2025
