Published: Oct 08, 2025
A lot has changed since we shipped same-document view transitions in 2023.
In 2024 we shipped cross-document view transitions, added refinements such as view-transition-class
and view transition types, and also welcomed Safari in adding support for view transitions.
This post gives you an overview of what changed for view transitions in 2025.
Better browser and framework support
Same-document view transitions are about to become Baseline Newly available
A focus area of Interop 2025 is the View Transition API, specifically same-document view transitions with document.startViewTransition(updateCallback)
, view-transition-class
, auto-naming with view-transition-name: match-element
, and the :active-view-transition
CSS selector.
Firefox intends to include these features in the upcoming Firefox 144 release which becomes stable on October 14, 2025. This will make these features Baseline Newly available.
Support for the View Transition API is now in React core
Throughout the year, the React team has been working on adding view transitions to the core of React. They announced react@experimental
support back in April and this week, at React Conf, they moved support of it into react@canary
which means the design is close to final.
function Child() {
return (
<ViewTransition>
<div>Hi</div>
</ViewTransition>
);
}
function Parent() {
const [show, setShow] = useState();
if (show) {
return <Child />;
}
return null;
}
You can check out React's <ViewTransition>
docs for all details or watch this talk by Aurora Scharff for a good introduction on the topic.
Recently shipped features
Auto-name elements with view-transition-name: match-element
Browser Support
To mark an element to be snapshotted as part of a view transition, you give it a view-transition-name
. This is key to view transitions, as it unlocks features such as transitioning between two different elements. Each element has the same view-transition-name
value at each side of the transition, and view transitions take care of things for you.
However, uniquely naming elements can become cumbersome when transitioning a lot of elements that don't really change. If you have 100 elements that move in a list, you have to come up with 100 unique names.
Thanks to match-element
you don't need to do all that. When using this as the value for view-transition-name
, the browser will generate an internal view-transition-name
for every matched element based on the element's identity.
In the following demo this approach is used. Each card in the row gets an automatically generated view-transition-name
.
.card {
view-transition-name: match-element;
view-transition-class: card;
}
#targeted-card {
view-transition-name: targeted-card;
view-transition-class: none;
}
The one card that enters or exits gets an explicit name. That name is used in the CSS to attach specific animations onto that snapshot. The snapshots of all other cards are styled using the view-transition-class
associated with them.
/* Style all pseudos with the class .card */
::view-transition-group(*.card) {
animation-timing-function: var(--bounce-easing);
animation-duration: 0.5s;
}
/* Style only the targeted-card's pseudos */
::view-transition-old(targeted-card):only-child {
animation: animate-out ease-out 0.5s forwards;
}
::view-transition-new(targeted-card):only-child {
animation: animate-in ease-in 0.25s forwards;
}
DevTools now shows rules targeting pseudos that use a view-transition-class
To debug view transitions, you can use the Animations panel from DevTools to pause all animations. This gives you time to inspect the pseudo-elements without having to worry that the view transition will reach its finished state. You can even manually scrub through the animation's timelines to see how the transitions play out.
Previously, when inspecting one of the ::view-transition-*
pseudo-elements, Chrome DevTools did not expose rules targeted to pseudos using their set view-transition-class
. This changed in Chrome 139, which added the functionality.

view-transition-group
pseudo-element in the cards demo. The styles tab shows the rules affecting that pseudo, including the rule that uses the view-transition-group(*.card)
selector.Nested view transition groups are available from Chrome 140
Browser Support
When a view transition runs, it renders the snapshotted elements in a tree of pseudo-elements. By default, the generated tree is "flat". This means that the original hierarchy in the DOM is lost, and all captured view transition groups are siblings under a single ::view-transition
pseudo-element.
This flat tree approach is sufficient for many use-cases, but becomes problematic when visual effects such as clipping or 3D transforms are used. These require some hierarchy in the tree.
Thanks to "Nested view transition groups" you can now nest ::view-transition-group
pseudo-elements within each other. When view transition groups are nested, it's possible to restore effects such as clipping during the transition.
Learn how to use view transition groups
Pseudo-elements now inherit more animation properties
When you set one of the animation-*
longhand properties on a ::view-transition-group(…)
pseudo, the contained ::view-transition-image-pair(…)
, ::view-transition-old(…)
, and ::view-transition-new(…)
also inherit that property. This is handy because it automatically keeps the cross-fade between the ::view-transition-new(…)
and ::view-transition-old(…)
in sync with the ::view-transition-group(…)
.
::view-transition-group(.card) {
animation-duration: 0.5s;
}
Initially this inheritance was limited to animation-duration
and animation-fill-mode
(and later animation-delay
as well), but now this has been extended to inherit more animation longhands.
Browsers that support view transitions, now should have the following in their user-agent stylesheet now
:root::view-transition-image-pair(*),
:root::view-transition-old(*),
:root::view-transition-new(*) {
animation-duration: inherit;
animation-fill-mode: inherit;
animation-delay: inherit;
animation-timing-function: inherit;
animation-iteration-count: inherit;
animation-direction: inherit;
animation-play-state: inherit;
}
The pseudo-elements inheriting more properties shipped in Chrome 140.
The execution of the finished
promise callback no longer waits for a frame
When using the finished
promise to execute a callback, Chrome used to wait for a frame to be produced before executing that logic. This could cause a flicker at the end of the animation when script moves some styles around in an attempt to preserve a visually similar state.
document.startViewTransition(() => {
if (from) {
dfrom.classList.remove("shadow");
dto.appendChild(target);
} else {
dto.classList.remove("shadow");
dfrom.appendChild(target);
}
}).finished.then(() => {
if (from) {
dto.classList.add("shadow");
} else {
dfrom.classList.add("shadow");
}
from = 1 - from;
});
This change in timing rectifies the situation by moving the view transition clean up steps to run asynchronously after the lifecycle is completed. This ensures that the visual frame produced at finished
promise resolution still maintains the view transition structure, thereby avoiding the flicker.
This timing change shipped in Chrome 140.
Upcoming features
The year hasn't finished yet, so there's still some time to ship some more features.
Scoped view transitions are ready for testing in Chrome 140
Scoped view transitions is a proposed extension to the View Transition API which lets you start a view transition on a subtree of the DOM by calling element.startViewTransition()
(instead of document.startViewTransition()
) on any HTMLElement
.
Scoped transitions allow multiple view transitions to run at the same time (as long as they have different transition roots). Pointer events are prevented on only that subtree (which you can re-enable), rather than the whole document. In addition, they let elements outside of the transition root be painted on top of the scoped view transition.
In the following demo, you can move a dot within its container by clicking one of the buttons. This can be done with document-scoped view transitions or element-scoped view transitions, allowing you to see how they behave differently.
The feature is ready for testing from Chrome 140 with the "Experimental Web Platform features" flag enabled in chrome://flags
. We're actively looking for developer feedback.
The position of ::view-transition
will change from fixed
to absolute
in Chrome 142
The ::view-transition
pseudo is currently positioned using position: fixed
. Following a CSS Working Group resolution this will change to position: absolute
.
This position
value change from fixed
to absolute
–which is coming to Chrome 142–is not visually observable because the containing block of the ::view-transition
pseudo is the snapshot containing block anyway. The only observable effect is a different position
value when doing a getComputedStyle
.
document.activeViewTransition
is coming to Chrome 142
When a view transition is started, a ViewTransition
instance gets created. This object contains several promises and functionality to track the transition progress, as well as allow manipulations such as skipping the transition or modifying its types.
Instead of requiring you to manually keep track of this instance, Chrome now provides a document.activeViewTransition
property that represents this object. If no transition is ongoing, its value is null
.
For same-document view transitions, the value gets set when you call document.startViewTransition
. For cross-document view transitions, you can access that ViewTransition
instance in the pageswap
and pagereveal
events.
Support for document.activeViewTransition
is about to ship in Chrome 142.
Prevent a view transition from automatically finishing with ViewTransition.waitUntil
A view transition automatically reaches its finished
state when all its animations are finished. To prevent this automatic finishing, you can soon use ViewTranistion.waitUntil
. When passing in a promise, the ViewTransition
will only reach its finished
state when that passed promise is also resolved.
const t = document.startViewTransition(…);
t.waitUntil(async () => {
await fetch(…);
});
This change is coming later this year and will allow to, for example, await a fetch
or unlock the easier implementation of a scroll-driven view transition.
What's next
As you can see we haven't been sitting still since we initially shipped View Transitions in 2023. We're looking forward to shipping scoped view transitions in the future and, as always, are open to feedback.
If you have a question about view transitions, reach out to us on social media. Feature requests for view transitions can be filed at the CSS WG. Should you run into a bug, file a Chromium bug to let us know.