The current state of View Transitions is nice, but it could be even better …

~

The clip-path problemAn area where View Transitions fall short is how it handles clip-path, border-radius, opacity, …

Take this demo, which has a view-transition-name on the grey circle and a view-transition-name on the text contained within that circle.

https://www.bram.us/wordpress/wp-content/uploads/2024/09/view-transitions-capture-mode-before.mp4As you can see in the recording, the snapshots cross-fade whereas you’d most likely want the clip-path of the circle to actually animate instead.

Also, the nested text bleeds out of its container; this because the snapshots are a flat list instead of a nested tree:

::view-transition├─ ::view-transition-group(card)| └─ ::view-transition-image-pair(card)| ├─ ::view-transition-old(card)| └─ ::view-transition-new(card)└─ ::view-transition-group(text) └─ ::view-transition-image-pair(text) ├─ ::view-transition-old(text) └─ ::view-transition-new(text) While this outcome of these View Transition limitations could be acceptable in some cases, here it is not.

~

It can be betterBut what if this issues could be solved? So that you’d get the following instead:

– The clip-path on the circle actually transitions
– The text stays clipped by the circle

Like so:

https://www.bram.us/wordpress/wp-content/uploads/2024/09/view-transitions-capture-mode-after.mp4That’s much better, right?

To achieve this, there are 2 changes needed for View Transitions:

  1. A way to preserve the tree when building the View Transition pseudos.
  2. A new capture mode that captures certain properties (such as clip-path, border-radius, opacity, …) individually and copies them onto the ::view-transition-group().

Combine the two, and you are able to get what you see in that second recording there 🙂

~

It will be betterAt the time of writing, Chrome is actively working on implementing these two new features, gated behind a feature flag. To try these out, you need Chrome Canary with Experimental Web Platform Features turned on.

  1. The new view-transition-group property – part of the View Transitions L2 specification – allows you to determine where to place the snapshot. In the demo shown before, I have the text’s pseudos be nested inside the box group pseudo, like so:

.card {view-transition-name: card;}.card a {view-transition-name: text;view-transition-group: card; /* 👈 Make the pseudo-tree for this “text” snapshot to be nested inside the “card” pseudo-tree */}

::view-transition└─ ::view-transition-group(card) ├─ ::view-transition-image-pair(card) | ├─ ::view-transition-old(card) | └─ ::view-transition-new(card) └─ ::view-transition-group(text) └─ ::view-transition-image-pair(text) ├─ ::view-transition-old(text) └─ ::view-transition-new(text) You can also use a value of nearest to make it less explicit 2. As for the capturing, Chrome is experimenting with a new capture mode that animates a select set of properties directly onto the ::view-transition-group().

The set of properties we are looking at are clip-path, border-radius, opacity, mask, filter, and clip properties.

You can already try this out in Chrome Canary but note that the implementation still needs some work as the border-radius and clip properties aren’t implemented yet.

If all goes well, this new mode will eventually replace the old mode.

Pretty sweet, right?

~

🔥 Like what you see? Want to stay in the loop? Here's how:

  • Follow @bramus on Twitter
  • Follow @bramus on Mastodon
  • Follow @bramusblog on Twitter
  • Follow bram.us using RSS