Skip to content

[css-view-transitions-1] Handling mix-blend-mode on elements captured for a transition #8962

Closed
@khushalsagar

Description

@khushalsagar

Summarizing the discussion here.

Let's say a view transition is capturing the root and element foo, and foo is semi-transparent with a non-normal mix-blend-mode. And let's say the author defines a very basic animation, e.g. sliding the old root out to the right and element foo out to the left to reveal the new document underneath.

The mode specifies how an element blends into its target stacking context. There is no conceptual way to bake the blending mode into the element's image itself so capture the image ignores this mode. But what this means is that as soon as the transition starts, the blending of foo against its background changes, resulting in a visible change in the color of foo.

One way this could be handled is to have the mix-blend-mode on one the ::view-transition pseudos which will display this image. But that has the following issues:

  1. The mix-blend-mode can be copied over to the replaced pseudo which is displaying the image. But by design, the mix-blend-mode on the ::view-transition-old/::view-transition-new pseudos is set to plus-lighter for the perfect cross-fade. The cross-fade shouldn't be noticeable if the images are exactly the same.
  2. The mix-blend-mode can be copied over to the ::view-transition-group for foo. It would then be conceptually similar to the element's viewport position, properties which don't make sense for the element in isolation but define how the element is laid out and composited into the Document embedding it. Except as opposed to transform, there is no way to animate it. So the mix-blend-mode will immediately flip from the old to new value instead of interpolating.

Note that option 2 above only works if the element's closest ancestor that is also being captured into an image is the root. For example, if you have a tree like this:

root
|_B mix-blend-mode: multiply;
   |_C mix-blend-mode: multiply;

The blending order in the DOM is : Blend(root, Blend(B, C). If B and C are being captured for a transition, then the pseudo tree is:

::view-transition-group(root)
|_::view-transition-image-pair(root)
    |_::view-transition-old(root)
    |_::view-transition-new(root)
::view-transition-group(B)
|_::view-transition-image-pair(B)
    |_::view-transition-old(B)
    |_::view-transition-new(B)
::view-transition-group(C)
|_::view-transition-image-pair(C)
    |_::view-transition-old(C)
    |_::view-transition-new(C)

root, B and C become siblings so the blending order is Blend(Blend(root, B), C) which is not the same as what's in the DOM.

We have the same problem with a bunch of other properties that depend on the DOM's hierarchy. For example, as soon as the transition starts you'll stop being clipped by an ancestor which is participating in a transition. Nested transition groups is the principled fix for it. Authors would opt into this mode in which case group pseudo for C will be nested inside group pseudo for B which itself will be nested inside group pseudo for root.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions