Skip to content

Commit 12ebe16

Browse files
committed
Bit on manipulating captured elements of the ::view-transition-ne() pseudo-element
1 parent 1b99aaa commit 12ebe16

4 files changed

Lines changed: 46 additions & 18 deletions

File tree

src/content/docs/basics/styling.mdx

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { Steps } from "@astrojs/starlight/components";
1212

1313
The animations introduced by the View Transition API are controlled by CSS rules. The way to make the animations fit your expectations is to alter the [default animation](/basics/default-animations/) by overriding the styles for the [pseudo elements](/basics/pseudos/).
1414

15-
To do this efficiently you should know what the View Transition API defines as defaults and how to easily change these styles if needed. To simplify styling, level 2 of the API introduced helpers in form of the `view-transition-class` property and the `:active-view-transition*` pseudo-classes.
15+
To do this efficiently you should know what the View Transition API defines as defaults and how to easily change these styles if needed. To simplify styling, level 2 of the API introduced helpers in form of the `view-transition-class` property and the `:active-view-transition...` pseudo-classes.
1616

1717
## Styling Tasks for View Transitions
1818

@@ -117,18 +117,12 @@ If both, the old image and the new image for `x` exist, the API defines a [morph
117117

118118
}
119119
@keyframes -ua-view-transition-group-anim-x {
120-
0% {
120+
from {
121121
backdrop-filter: <old backdrop filter>;
122122
transform: <matrix to exactly cover the old element>;
123123
height: <old height>;
124124
width: <old width>;
125125
}
126-
100% {
127-
backdrop-filter: <new backdrop filter>;
128-
transform: <matrix to exactly cover the new element>;
129-
height: <new height>;
130-
width: <new width>;
131-
}
132126
}
133127
```
134128

@@ -148,16 +142,11 @@ Just like with group animations, the transition begins with the values of the ol
148142
animation-name: -ua-view-transition-group-children-anim-x;
149143
}
150144
@keyframes -ua-view-transition-group-children-anim-x {
151-
0% {
145+
from {
152146
border-width: <old border-width>;
153147
border-radius: <old border-radius>;
154148
corner-shape: <old corner-shape>;
155149
}
156-
100% {
157-
border-width: <new border-width>;
158-
border-radius: <new border-radius>;
159-
corner-shape: <new corner-shape>;
160-
}
161150
}
162151
```
163152

@@ -458,8 +447,47 @@ The scope of view transitions is the whole document. Until (element) _scoped_ vi
458447

459448
Note that `:root` has a different meaning inside shadow DOMs. But that is a whole different story.
460449

461-
With scoped view transitions, `:root::view-transition*` will still select only pseudo-elements of the document root, while `::view-transition*` will target pseudo-elements of any element. Should I prefix all rules with `:root`? Right now, I do not. Scoped view transitions will be another game changer, and I expect to refactor things anyway once they become available.
450+
With scoped view transitions, `:root::view-transition...` will still select only pseudo-elements of the document root, while `::view-transition...` will target pseudo-elements of any element. Should I prefix all rules with `:root`? Right now, I do not. Scoped view transitions will be another game changer, and I expect to refactor things anyway once they become available.
462451

463452
When you use these patterns in your own stylesheets, be aware that the specificities differ: `:root::view-transition-group(x)` with a specificity of _(0, 1, 1)_ is more specific than `::view-transition-group(x)` with a specificity of _(0, 0, 1)_.
464453

465454
Now you might conclude that you also need to prefix your view transition pseudo-elements with `:root` if you want to override the defaults. That is not the case. The user agent stylesheet has the least important origin and is overridden by user stylesheet rules independent of specificity.
455+
456+
## Styling Underlying Captured Elements
457+
458+
This might sound weird. The main effect of the View Transition API is to create pseudo-elements for the DOM elements that you have assigned a view transition name to. These pseudo-elements are used to create the animations. So why should you care about styling the original DOM elements? Stay with me, this might become a very useful tool in your toolbox.
459+
460+
OK, some background:
461+
- Captured elements are the elements in the original DOM that were captured to create the view transition pseudo-elements.
462+
- The captured element of the `::view-transition-old(x)` pseudo-element was snapshotted during the early capture phase. It may still exist in the current DOM, but it may also be removed, and it surely is in the case of cross-document view transitions. Conceptually, it is gone.
463+
- The captured element of the `::view-transition-new(x)` pseudo-element is most likely still in the DOM, but it is not visible during the view transition. You can only see it through the `::view-transition-new(x)` pseudo-element. The nature of `::view-transition-new(x)` as a replaced element, where the content is the captured element, means that whatever you do to the captured element is immediately reflected by the `::view-transition-new(x)` pseudo-element.
464+
465+
This last observation is why it is so useful to know how to use both tools: styling the `::view-transition-new(x)` pseudo-element and styling its underlying captured element.
466+
467+
**Styling Pseudo-Element of the Captured Element:**
468+
Whatever is simple to do with an image is a good candidate for styling the pseudo-element:
469+
- Changing its size, position, and transformation
470+
- Changing its opacity and mix-blend-mode
471+
- Adding filters and animations
472+
473+
**Styling the Captured Element of the New Image:**
474+
There are some things that you cannot do with an image of a DOM element. That is when you want to interact with the underlying captured element. For example, you might want to change the background colour of the captured element during the view transition. Or you might want to change the content of a text element, or the way its text wraps.
475+
476+
Just be aware that the default styling for the `::view-transition-new(x)` pseudo-element is a fade-in and therefore it is typically not visible at the beginning of the view transiton.
477+
478+
If your old and new image are identical, you can remove the old image and the default animation of the new image:
479+
```css
480+
::view-transition-old(x) {
481+
display: none;
482+
}
483+
::view-transition-old(x),
484+
::view-transition-new(x) {
485+
animation-name: none;
486+
}
487+
```
488+
A practical example where you will do this? A view transition with a video player. That way the video continues to play during the whole transition, no frozen images.
489+
490+
**Moving the Captured Element of the New Image:**
491+
The captured element does not only provide the content for the displaced `::view-transition-new(*)` element, it also provides the target values for the automatically generated[group animation](#group--morph-animation).
492+
493+
So if you want to change the target position, size, or transformation of the `::view-transition-group(x)` pseudo-element, you can do this by manipulating the captured element of the new image. This is a powerful tool to change the effect of the morph animation without the need to override the generated keyframes for the group animation.

src/content/docs/fwvt/playing.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ You are curious about [`useTypesPolyfill: "always"`](/tools/utensil-drawer/#uset
212212

213213
## Curved Group Animations
214214

215-
If a view transition group contains an image pair with both an old and a new image, the View Transition API [creates an animation](/basics/default-animations/#morphing-animation-details) that moves the group in a straight line from the position and size of the named element in the old DOM to the position and size of the identically named element in the new DOM.
215+
If a view transition group contains an image pair with both an old and a new image, the View Transition API [creates an animation](/basics/default-animations/#morphing-animation-details) that moves the group in a straight line from the position and size of the captured element in the old DOM to the position and size of the identically captured element in the new DOM.
216216

217217
The group animation dynamically created by the View Transition API is just a regular CSS animation.
218218
You can inspect or override every aspect of it, including the generated keyframes.

src/content/docs/tips/css.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ Currently, I use the following approach to organize CSS definitions for view tra
9898
1. I check for buttons and links that will end up being captured by pseudo-elements. Those will not be interactive during the animation and they definitively should look disabled.
9999
1. Next I figure out which of the pseudo-elements and animations generated by the View Transition API are not required for the effect, like cross-fades of identical images, or old images that can be replaced by the new images (or vice versa), or group animation that do not change the geometry.
100100
1. The next task is defining the styling of the view transition pseudo-elements. Its in the nature of view transitions that this styling often addresses `animation-*` properties. But there are also often other fun properties for clipping / masking, object placement, perspective, and others that might be worth to think of.
101-
1. In cases where I want to take advantage that the `::view-transition-new` pseudo-elements are life images of their named elements, I define the styling for those.
101+
1. In cases where I want to take advantage that the `::view-transition-new` pseudo-elements are life images of their captured elements, I define the styling for those.
102102
1. Finally, I define new key frames and timing function as required, always checking whether there is some potential for standardization and reuse.
103103

104104
### The Active Type Guard

src/content/docs/tips/view-transition-fails-and-fixes.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ Tip: Move the view transition styling for cross-document view transitions to a g
254254

255255
<details name="fail" class="c s">
256256
<summary>Stacking order issues</summary>
257-
The view transition pseudo-elements are created in the order in which their named elements are encountered in the old DOM. After that come the pseudo-elements for the named elements that are part of the new DOM, only. Within an image pair, the new image is created after the old image.
257+
Capturing visits the elements in paint order and the view transition pseudo-elements are created in the order in which their named elements are encountered in the old DOM. After that come the pseudo-elements for the named elements that are part of the new DOM, only. Within an image pair, the new image is created after the old image.
258258

259259
Pseudo-elements are rendered in the order they were created. Thus elements from the new DOM might obscure elements from the old DOM. And within an image pair, the new image is painted in front of the old one.
260260

0 commit comments

Comments
 (0)