View Transitions Major Update: Cross-Browser Support and Four New Features Explained

A complete breakdown of View Transitions' latest updates: cross-browser support, auto-naming, nested groups, and scoped transitions.
Based on the latest Google CSS Podcast episode, this article covers key View Transitions updates. Chrome and Safari now fully support both same-document and cross-document transitions, with Firefox close behind. New view transition types with the `:active-view-transition-type()` pseudo-class enable fine-grained control per navigation scenario. The `match-element` value eliminates manual naming for large element sets, and can be paired with the enhanced `attr()` function for stable cross-document identifiers. Chrome 140's nested view transition groups enable coordinated parent-child transitions, while scoped view transitions (testable in Canary) allow transitions on subtrees only — enabling simultaneous multi-area transitions and fixing the longstanding page-freeze and z-index issues.
View Transitions is one of the most exciting UI capabilities in modern web development, enabling developers to create smooth, seamless transitions between two states of a website — giving web apps an experience close to native applications. In the latest episode of Google's official CSS Podcast, hosts Bramus and Una reviewed a series of significant changes in the View Transitions space since the foundational episode (Episode 89). This article systematically walks through all of these updates.
Browser Support: From Experimental to Cross-Browser Reality
When View Transitions first launched, only same-document view transitions had limited support. The situation has improved dramatically: both Chrome and Safari now support both same-document and cross-document view transitions.
At the time of recording, Firefox had already enabled same-document view transitions behind a flag in Nightly builds, with a stable release expected later this year — which would check off this capability on the Interop 2025 dashboard.
Two concepts worth clarifying: same-document view transitions are triggered via JavaScript within the same page, typically used for state changes inside single-page applications (SPAs); cross-document view transitions are triggered when navigating from one page to another, applicable to multi-page applications (MPAs) — what we commonly call "regular websites."
Notably, Firefox's implementation includes support for the view-transition-class property, but does not yet support view transition types, a newer capability.
Interop is an annual interoperability initiative jointly launched by major browser vendors including Apple, Google, Mozilla, and Microsoft, aimed at collaboratively addressing areas of inconsistent browser implementation on the web platform. Each year, vendors jointly agree on a priority list. Having a feature included on the Interop dashboard means all participating parties commit to implementing it within that year, measured by pass rates on a unified test suite (Web Platform Tests). View Transitions being included in Interop 2025 means Firefox's stable support is expected to land within 2025, after which developers can use the feature across all three major browsers without a polyfill.
View Transition Types: Fine-Grained Control Over Transition Behavior
View Transition Types allow you to assign one or more "types" to a view transition, and restrict certain CSS to only apply when a specific type is active. This is especially useful in large team collaborations, or when you need different transitions depending on the source or destination page.
Take blog pagination as an example: when switching between "previous/next" pages, you might want to snapshot the pagination component itself, the post title, and even the author avatar; but when navigating from a blog post to the "About" page, you don't want to capture those details — you only want to capture the site header and the entire content area.
According to the hosts, this is exactly how Google Search's AI Mode team uses it — when entering or exiting AI Mode, they snapshot larger UI building blocks as part of the transition; once inside AI Mode, the view transition needs to capture entirely different elements. A corresponding case study is available on developer.chrome.com.

On the syntax side, same-document transitions can now pass an object to document.startViewTransition() containing two properties: callback and types (an array). Cross-document transitions can add a types descriptor inside the @view-transition rule, with a comma-separated list as the value.
Once types are set, you can respond to them in CSS via the new functional pseudo-class :active-view-transition-type(). It accepts a type as a parameter, and when a transition with that type is active, the selector applies to the transition root element. A major advantage of this selector is that it takes effect the moment the transition activates — from before the old snapshot is captured, all the way until the transition ends. There's also a companion :active-view-transition pseudo-class for matching the element that triggered the transition.
match-element: Say Goodbye to Manual Naming
When rebuilding card enter/exit animations with View Transitions, a clear pain point is that you must assign a unique view-transition-name to each card — which often means dynamically generating names in JavaScript for every single card. As the hosts put it: "I just want to give each card a transition name, but I don't care what it is, and I don't want to manage these unique identifiers."
There's now a solution: the special value match-element for view-transition-name. It automatically generates a unique transition name based on the element's "identity." So for 100 cards, you no longer need to come up with 100 names — a single .card { view-transition-name: match-element; } does the job.

There are limitations to be aware of: this value is based on the element's internal number (assigned by the browser when the element is created), so it cannot be used for cross-document transitions, since elements in different documents have their own independent numbering. Similarly, issues arise when removing and reinserting elements within the same document — the removed element and the newly created node have different internal numbers. When using frameworks, auto-rebuilding of the DOM tree may also result in elements that "look the same but are actually different."
The workaround is to use the enhanced attr() function: read the element's ID or data attribute as a stable identifier. The syntax looks like attr(id type(<custom-ident>), match-element) — first retrieve the attribute value with a specified type, falling back to match-element if that fails. The hosts noted they hope other browser vendors will quickly adopt this powerful capability — it may appear in Interop 2026.
The enhanced
attr()function mentioned here is a new capability from the CSS Values Level 5 specification. Unlike the oldattr()from CSS 2.1 which could only return strings, the new version supports specifying the return type viatype()syntax (e.g.,<custom-ident>,<color>,<length>), and accepts a second parameter as a fallback. This makes it possible to read semantically typed values from HTML attributes, allowing business identifiers already present on elements (likeidordata-key) to be reused directly in CSS properties — without extra JavaScript manipulation. Browser support for this feature is still limited; keep an eye on compatibility when using it withmatch-element.
Nested View Transition Groups: Respecting DOM Hierarchy
Supported since Chrome 140, nested view transition groups allow one or more view-transition-group pseudo-elements to be nested inside another. If you've run into clipping issues, or need a group of elements to move as a whole inside another element, this is the feature for you. It also supports nested 3D transforms, and correctly applies opacity, masking, and filter effects.
A typical example: a card containing multiple avatars, where when the card transitions from a sidebar to the main column while the avatars are also scaling, you want the avatars to move along as part of the card's content. Without nested groups, the transition group pseudo-elements for the card and avatars become "siblings" rather than parent-child, making this impossible.

To create nested groups, use the new view-transition-group property: set it to contain on the parent element to have it contain all child element snapshots; or set it to nearest (to find the nearest named parent element) or a custom identifier matching the parent element's name on each child element. Both approaches produce the same result — in the pseudo-element tree, the avatar's transition group becomes a child of the card's transition group.
However, they aren't direct children — they're grouped together under a new pseudo-element called ::view-transition-group-children. To clip content, you need to set overflow: clip on this new pseudo-element. Make sure to use Chrome 140 or newer to experience the related demos.
Scoped View Transitions: Running Only on a Subtree
If you only want to clip within a single parent element, a better fit than nested groups is scoped view transitions — currently testable in Chrome Canary (requires enabling the experimental web platform features flag). Official feedback is actively being sought.
The core change is: instead of calling document.startViewTransition(), you call element.startViewTransition(). The entire transition subtree is injected only into that element, not the entire document. The rest of the logic is the same as regular same-document transitions, but with a key difference — the view-transition overlay pseudo-element is injected into the calling element, meaning the rest of the page remains interactive while the transition runs. This solves the longstanding View Transitions pain point of "the entire page freezing during a transition."

Scoped transitions also bring several valuable side effects: First, multiple transitions can run simultaneously, as long as they are in different subtrees (e.g., a chat component and a header transitioning at the same time). Second, they alleviate the longstanding z-index problem. Previously, transition pseudo-elements were painted on top of the entire document (including the top layer), causing popovers and similar elements to be unexpectedly covered — developers had to add transition names to popovers as a hack. In most cases, this is no longer necessary. Third, content is automatically clipped.
One difference to note: with scoped transitions, the container itself does not move with the transition; nested view transition groups do. The hosts' current rule of thumb is: try to solve the problem with scoped transitions first, and only consider nested view transition groups if that doesn't work — though best practices are still being explored.
The top layer is a special, independent layer in the browser's rendering model. Elements such as
<dialog>, elements with thepopoverattribute, and fullscreen elements are promoted to this layer to ensure they always render above the rest of the page content, unaffected byz-indexandoverflow: hidden. However, traditional View Transitions pseudo-elements are painted at the very top of the entire document — even above the top layer — causing popovers and modals that should appear on top to be covered during transition animations. Scoped view transitions inject pseudo-elements into a specified sub-element rather than the<html>root node, fundamentally avoiding stacking conflicts with the top layer. This is the official solution to that problem.
Also: document.activeViewTransition
One last, smaller addition currently in development is the document.activeViewTransition property. It lets you directly access the currently active view transition object (if one exists). Previously, achieving this required manually tracking and recording the transition when you started it — that will no longer be necessary. At the time of recording, the property hadn't landed in any browser yet, but it's expected to appear in Canary or even Chrome Stable soon.
Summary
View Transitions is rapidly evolving from "an interesting experimental feature" to "a production-ready UI capability." The expansion of cross-browser support, the developer experience improvements from match-element, and the coverage of complex scenarios through nested groups and scoped transitions are all bringing web apps closer to the fluid experience of native applications. For developers who want their websites to "morph" more naturally and feel more app-like, now is a great time to dive deep into this technology.
Related articles

Python 3.15 New Feature: Is the sentinel Type Better Than None?
Python 3.15 adds the sentinel type, using named unique sentinel objects to replace None and bare object(), resolving confusion among missing values, explicit emptiness, and invalid input while avoiding type hint failures.

Deep Learning's Three Architectures and the Universal Approximation Theorem: A Complete Guide to MLPs, CNNs, and Transformers
Explaining the inductive bias differences among MLP, CNN, and Transformer, the existence meaning of the Universal Approximation Theorem (UAT), and the role of Taylor expansion in approximation analysis, while clearing up common misconceptions.

GitLab Emergency Patch Release: Analysis of Critical Security Fixes
GitLab releases critical patch 19.5.1, sparking 355 points of discussion on Hacker News. This article analyzes the background, upgrade steps for self-hosted instances, and verification points to help DevOps teams respond quickly to security updates.