Demystifying the View Transition Pseudo Tree

ibobev1 pts0 comments

Demystifying the View Transition Pseudo Tree – Master.dev Blog

/ BLOG

CSSView Transitions

Demystifying the View Transition Pseudo Tree

Cyd Stumpel<br>on<br>June 10, 2026

Every time a view transition is initiated, a pseudo-element is added to the HTML element for the duration of the view transition. This acts as a snapshot overlay across your entire page.

Each pseudo-element plays a distinct role in how the view transition animates. The browser does most of the heavy lifting, which makes it a little hard to see what’s actually happening under the hood. This article breaks down each pseudo-element in the tree so you know exactly what to target when you need to customize things.

The View Transition Pseudo Tree

All elements with a view-transition-name CSS property will be added to the view transition pseudo tree every time a view transition is called. By default, only the HTML tag gets a view-transition-name, the root view transition group is the same size as the HTML element and covers all interactive elements.

This is why your website may not be interactive during a view transition!

::view-transition<br>└─ ::view-transition-group(root)<br>└─ ::view-transition-image-pair(root)<br>├─ ::view-transition-old(root)<br>└─ ::view-transition-new(root)

You can see the pseudo-element tree in DevTools during a View Transition.

The pseudo tree will get a view-transition-group for every named element, those elements are separated from the root view transition and put on top of it. The value of the view-transition-name will be used in the view transition group and its children. See the screenshot above where the active view transition had view-transition-name: blob;.

/*<br>Adding a view-transition-name separates the element<br>from the root view transition and puts it on top<br>in the view transition pseudo tree<br>*/<br>.header-image {<br>view-transition-name: header-image;<br>}Code language: CSS (css)

::view-transition<br>└─ ::view-transition-group(root)<br>└─ ::view-transition-image-pair(root)<br>├─ ::view-transition-old(root)<br>└─ ::view-transition-new(root)<br>└─ ::view-transition-group(header-image)<br>└─ ::view-transition-image-pair(header-image)<br>├─ ::view-transition-old(header-image)<br>└─ ::view-transition-new(header-image)

::view-transition-group

The view-transition-group pseudo-element is responsible for the animation of the position, size, and rotation, this is all generated and applied automatically.

CodePen Embed Fallback

The browser positions all view transition groups absolutely at the top-left corner.

/* user agent stylesheet */<br>::view-transition-group(*) {<br>position: absolute;<br>top: 0px;<br>left: 0px;<br>animation-duration: 0.25s;<br>animation-fill-mode: both;<br>}Code language: CSS (css)

The keyframe then moves the element to the position where it was when the view transition was called using a matrix animation:

/* user agent stylesheet */<br>@keyframes -ua-view-transition-group-anim-box {<br>0% {<br>transform: matrix(1, 0, 0, 1, 8, 8);<br>width: 100px;<br>height: 100px;<br>backdrop-filter: none;<br>}Code language: CSS (css)

Only a start keyframe is added to the animation; it will then animate to the end state that’s set by the browser on the view transition group:

/* user agent stylesheet */<br>::view-transition-group(box) {<br>transform: matrix(1, 0, 0, 1, 108, 108);<br>width: 200px;<br>height: 200px;<br>/* [...] */<br>}Code language: CSS (css)

To simplify: this matrix animation animates the translateX and translateY from 8px to 108px.

The same thing is applied in reverse if you click the button again:

/* user agent stylesheet */<br>@keyframes -ua-view-transition-group-anim-box {<br>0% {<br>transform: matrix(1, 0, 0, 1, 108, 108);<br>width: 200px;<br>height: 200px;<br>backdrop-filter: none;

::view-transition-group(box) {<br>transform: matrix(1, 0, 0, 1, 8, 8);<br>width: 100px;<br>height: 100px;<br>/* [...] */<br>}Code language: CSS (css)

All this is handled by the browser, using the user agent stylesheet, often you don’t need to change anything about this animation, you can make it fit your website better using a custom duration, delay and ease. It’s good practice to add all changes to the animation property as individual properties (not using the animation shorthand) so you don’t inadvertently overwrite any of the default values or animations.

It’s also important to understand that many of the animation properties that you set on view transition pseudo-elements are inherited by their children. If you change the duration, fill-mode, delay, timing-function, iteration-count, direction or play-state of the view-transition-group , for example, it will also be applied to the view-transition-image-pair and view-transition-old and view-transition-new pseudo-elements.

::view-transition-image-pair

The sole purpose of view-transition-image-pair is to apply this rule:

/* user agent stylesheet */<br>::view-transition-image-pair(box) {<br>isolation: isolate;<br>}Code language: CSS (css)

Isolation is a CSS property that creates a new stacking context, meaning mix-blend modes set on children remain isolated and won’t mix with anything...

view transition group pseudo image root

Related Articles