v147 · web api · shipped
Element-scoped view transitions
Call element.startViewTransition() on any HTML element to run a view transition scoped to that subtree, rather than the entire document. Multiple element-scoped transitions can run concurrently, nested transitions work naturally, and position-fixed content outside the scope stays interactive throughout.
at a glance
| Shipped in | Chrome 147 (desktop + Android) |
|---|---|
| Status | Enabled by default |
| Flag | None |
| Standards position | Part of View Transitions Level 2 (W3C CSSWG) |
| Spec | CSS View Transitions Level 2 |
| Explainer | WICG/view-transitions — scoped-transitions.md |
| ChromeStatus | 5109852273377280 — Element-scoped view transitions |
why it exists
The original document.startViewTransition() freezes the entire page into a before/after snapshot, which means only one transition can run at a time and elements with position: fixed get captured in the snapshot, losing interactivity. Scoping the transition to a specific element removes all three problems: multiple independent parts of the page can animate simultaneously, the rest of the document stays live, and fixed-position chrome outside the scope is unaffected.
shape of the API
Element.startViewTransition() has the same call signature as Document.startViewTransition() — a callback or options object — but the scope of the captured snapshot is the element itself rather than the full document.
| Member | Type / Description |
|---|---|
element.startViewTransition(callbackOrOptions) |
Starts a view transition scoped to element. Returns a ViewTransition object (same as the document-level version). The element automatically gets view-transition-name: root within the scope. |
callbackOrOptions |
Either a callback function that performs the DOM update, or an options object { update, types }. The callback may return a Promise; the transition waits for it before snapshotting the new state. |
Automatic behaviours on the scope root
view-transition-name: root | Applied automatically so the root element participates in the transition |
view-transition-group: contain | Applied automatically to enable nested view-transition groups |
::view-transition-group-children(root) clips overflow | Content outside the element's bounds is clipped, matching the element's own overflow behaviour |
example
Animate a single list widget without freezing the page
const list = document.querySelector('ul.feed');
async function addItem(text) {
// Only the list animates; the header and sidebar stay interactive
await list.startViewTransition({
update() {
const li = document.createElement('li');
li.textContent = text;
list.prepend(li);
}
}).finished;
}
document.getElementById('add-btn').addEventListener('click', () =>
addItem('New entry ' + Date.now())
);
Run two concurrent transitions
// Both transitions run in parallel — not possible with document.startViewTransition()
const sidebar = document.querySelector('.sidebar');
const main = document.querySelector('main');
sidebar.startViewTransition(() => updateSidebar());
main.startViewTransition(() => updateMain());
Typed transitions (View Transitions Level 2)
list.startViewTransition({
types: ['slide-in'],
update() { list.prepend(newItem); }
});
// CSS: @keyframes and view-transition-type selector apply as normal
Source: Chrome for Developers — element-scoped view transitions guide and WICG explainer, May 2026.
browser support
| Browser | Support |
|---|---|
| Chrome 147+ | Enabled by default |
| Edge 147+ | Enabled by default (Chromium) |
| Firefox | No support yet |
| Safari | No support yet |