DigitalOcean provides cloud products for every stage of your journey. Get started with $200 in free credit!
The CSS view-transition-name
property uniquely identifies an element that can be used in a view transition.
card {
view-transition-name: card-transition;
}
We give the element a name (i.e., <custom-ident>
) that we reference or set the property to none
to exclude the element from view transitions.
The specification is not a standard just yet but describes view-transition-name
as a way of “tagging individually transitioning subtrees” which is a super fancy way of saying we want a certain element to be captured in a view transition. When we give an element a view-transition-name
, we’re effectively giving it access to a set of pseudo-elements for creating a view transition.
Syntax
view-transition-name: none | <custom-ident>;
- Initial value:
none
- Applies to: All elements
- Inherited: No
- Percentages: N/A
- Computed value: As specified
- Canonical order: By grammar
- Animation type: discreet
Property Values & Descriptions
/* <custom-ident> */
view-transition-name: banner;
view-transition-name: banner-transition;
view-transition-name: bannerTransition;
/* Keyword */
view-transition-name: none;
<custom-ident>
: A unique identifier used to define an element that can participate in a view transition, whether it is the “old” element or the “new” one that is transitioned to. We can’t use the wordsnone
orauto
for the value, as they are reserved global keyword values.none
: Removes the element from taking part in a view transition.
What the heck is a “captured element”?
It’s worth knowing because that’s exactly how the specification describes an element with a view-transition-name
declared on it. The basic idea of view transitions is that we “capture” an existing state as an image and transition between that snapshot and a new element.
When we “capture” an element, we’re sort of tracking it during the lifetime of the view transition, during which the element takes multiple forms. Here’s the process that a captured element follows, as provided by the spec, which goes further by calling a captured element a “struct” or a set of items:
- old image: A 2D bitmap or null. Initially null.
- old width / old height: an
unrestricted double
, initially zero. - old
transform
: a<transform-function>
, initially the identity transform function. - old
writing-mode
: Null or awriting-mode
, initially null. - old
direction
: Null or adirection
, initially null. - old
text-orientation
: Null or atext-orientation
, initially null. - old
mix-blend-mode
: Null or amix-blend-mode
, initially null. - old
backdrop-filter
: Null or abackdrop-filter
, initially null. - old
color-scheme
: Null or acolor-scheme
, initially null. - new element: An element or null. Initially null.
Those are all the pieces of a captured element used in a view transition. We capture a set of information about an element’s current (or “old”) state and transition it into a new element.
The name has to be unique
We can name a view transition anything we want (none
and auto
being the only exceptions) but it has to be unique in the sense that it is only applied to one rendered element on the current page.
The key word there is “rendered” because we can technically repurpose the same view-transition-name
on multiple elements. For example, you might want the same transition on a set of images but wouldn’t want to go through the work of naming each and every one. We can instead declare view-transition-name
on a certain class:
.image-transition {
view-transition-name: image-zoom;
}
Then we can set up JavaScript that that sets a variable for each image in the set, adds the .image-transition
class to the images, then triggers the transition with some action — like a click handler — on the image. From there, the script waits for the transition to wrap up, then removes the .image-transition
class so it can be applied to another clicked image.
// Create a variable for img elements in a .gallery
const image = document.querySelectorAll(".gallery img");
// When an image is clicked...
image.onclick = () => {
// If view transitions are *not* supported
if (!document.startViewTransition) {
// Run a fallback function
doSomething(image);
// If view transitions are supported
} else {
// Add the .image-transition class to the clicked image
image.classList.add("image-transition");
// Start the transition and save its instance in a variable
const transition = document.startViewTransition(() => doSomething(image));
// Wait for the transition to finish.
await transition.finished;
// Remove the class when finished
image.classList.remove("image-transition");
}
};
Another approach is to set view-transition-name
to a <custom-ident>
on the clicked image, wait for the transition to run, then swap out the <custom-ident>
with the none
value instead.
// Create a variable for img elements in a .gallery
const image = document.querySelectorAll(".gallery img");
// When an image is clicked...
image.onclick = () => {
// First, check if view transitions are supported
if (!document.startViewTransition) {
// Fallback if View Transitions API is not supported.
doSomething(image);
} else {
// Set `view-transition-name` with a <custom-ident>
image.style.viewTransitionName = "image-zoom";
// Start the transition and save its instance in a variable
const transition = document.startViewTransition(() => doSomething(image));
// Wait for the transition to finish.
await transition.finished;
// Set the transition name to `none` when finished
image.style.viewTransitionName = "none";
}
};
Specification
The view-transition-name
property is just one of several view-*
properties that are used together to register and manage view transitions that are part of the View Transitions Module Level 1 specification, which is currently a Candidate Recommendation Snapshot meaning it can be used where available, but is in the process of collecting feedback before formal recommendation. In other words, view-transition-name
and other related properties are experimental and not part of the standards just yet.
Browser support
It’s only Chrome and other Chromium-powered browsers at the moment. Keep an eye on the Caniuse pages for the most current support information for the view-transition-name
property and support for the none
value.
As far as browser support goes, we can use the view-transition-name
property to check whether or not the user’s browser supports the View Transitions API and provide a fallback for browsers that lack support. We could use a <custom-ident>
value to check support, but the none
value is probably a better bet since it is a consistent keyword and we definitely want that value supported if we’re working with view trasnsitions anyway.
/* If the View Transitions API is supported */
@supports (view-transition-name: none) {
}
/* If the View Transitions API is *not* supported */
@supports not (view-transition-name: none) {
/* Use a simple CSS animation if possible */
}
Similarly, we can check for support via JavaScript as well:
// If the View Transitions API is *not* supported.
if (!document.startViewTransition) {
doSomething());
// Otherwise, start the view transition
} else {
document.startViewTransition(() => doSomething());
}
Related
::view-transition
::view-transition { position: fixed; }
::view-transition-group
::view-transition-group(transition-name) { animation-duration: 1.25s; }
::view-transition-image-new
::view-transition-image-new(*) { animation-duration: 700ms; }
::view-transition-image-old
::view-transition-image-old(*) { animation-duration: 700ms; }
::view-transition-image-pair
::view-transition-image-pair(root) { animation-duration: 1s; }