view-transition-scope CSS property
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
The view-transition-scope CSS property enables the discoverability of elements with view-transition-name values set on them (for the purposes of creating view transition snapshots) to be isolated to a specific element subtree.
Syntax
/* Keyword values */
view-transition-scope: none;
view-transition-scope: all;
/* Global values */
view-transition-scope: inherit;
view-transition-scope: initial;
view-transition-scope: revert;
view-transition-scope: revert-layer;
view-transition-scope: unset;
Values
none-
The initial value. Discoverability of elements to snapshot during a view transition is not limited to a selected element's subtree.
all-
Discoverability of all snapshottable elements (with any non-
noneview-transition-name) during a view transition is limited to a selected element's subtree.
Description
When a view transition is triggered, as part of the process, the browser captures snapshots of elements that have a non-none view-transition-name set on them. These snapshots are then animated via CSS animations.
One issue that can arise is naming collisions between different view transitioned elements. Under normal circumstances, you can't have the same view-transition-name set on multiple elements — when the Element.startViewTransition() function is called to start the transition, the browser throws an InvalidStateError.
You could solve this problem by setting a view-transition-name of match-element on the elements, to let the browser auto-assign internal unique names, but this won't work if you are including multiple components from different sources that you don't control. A naming collision might still occur.
The view-transition-scope property was implemented so that view transitions can be made self-contained. When view-transition-scope: all is set on an element, it limits the transition scope to that element and its descendants, which can be used to solve the above problem.
Whenever a view transition is triggered, the browser automatically sets view-transition-scope: all on the transition scope's root element so that elements are only snapshotted and view transition animations applied inside the transition scope.
Formal definition
Value not found in DB!Formal syntax
view-transition-scope =
none |
all
Examples
>Demonstration of view-transition-scope
This example demonstrates the effect of view-transition-scope.
HTML
We include a <button> element to control updating the DOM, plus several components with the class change-me, some of which are nested, all wrapped in a <section> element.
<button>Update DOM</button>
<section>
<div class="change-me"><span>I can change</span></div>
<div class="change-me">
<span>I can change</span>
<div class="change-me"><span>I can change</span></div>
</div>
<div class="change-me"><span>I can change</span></div>
</section>
CSS
We start by setting the same view-transition-name on all components. We then set view-transition-scope: all on all of them, to isolate the view transition process for each one. We then set a longer animation-duration on all view transitions with this view-transition-name via the ::view-transition-group() pseudo-element.
.change-me {
background-color: white;
view-transition-name: para-change;
view-transition-scope: all;
}
::view-transition-group(para-change) {
animation-duration: 1s;
}
JavaScript
In our script, we start off by grabbing references to our button and the <div> elements (our components).
const btn = document.querySelector("button");
const divs = document.querySelectorAll("div");
Next, we define a function called updateDivs(), which toggles the text content of each component's nested <span> element between two values, and also toggles the component's foreground and background colors between two values.
function updateDivs() {
divs.forEach((div) => {
if (div.firstElementChild.textContent === "I can change") {
div.firstElementChild.textContent = "I have changed";
div.style.color = "white";
div.style.backgroundColor = "black";
} else {
div.firstElementChild.textContent = "I can change";
div.style.color = "black";
div.style.backgroundColor = "white";
}
});
}
Finally, we add a click event listener to the <button> element. When it is clicked, we first check whether startViewtransition() exists on the document
object — if not, we run updateDivs() and then return out of the function. This first part allows browsers that don't support view transitions to still update the DOM without error. Next, we run updateDivs() inside a startViewTransition() callback to trigger the view transition as the DOM updates.
btn.addEventListener("click", handleClick);
function handleClick(e) {
if (!document.startViewTransition) {
updateDivs();
return;
}
document.startViewTransition(() => {
updateDivs();
});
}
Result
Click the button to see the view transition. Now try the following:
- Inspect one of the
<div>elements. - In your browser DevTools' style panel, uncheck the
view-transition-scope: all;declaration to unapply it. - Now switch to the JavaScript Console.
- Press the "Update DOM" button again.
You should see that the view transition animation is not applied when the DOM changes, and you'll get an InvalidStateError in the console.
Specifications
| Specification |
|---|
| CSS View Transitions Module Level 2> # view-transition-scope-prop> |