Skip to content

[css-view-transitions-2]: Nested ::view-transition-group should have a container pseudo. #11926

Open
@vmpstr

Description

@vmpstr

One of the common use cases for view-transition-group: contain that we're considering is a scroller with items within in and a view transition that shuffles the items within the container.

This is achieved with something like

.container {
  view-transition-name: clipper;
  view-transition-group: contain;
}
.container > .item {
  view-transition-name: auto;
}

In the current spec this builds the following pseudo tree:

:root
|-::view-transition
| |-::view-transition-group(clipper)
|   |-::view-transition-image-pair(clipper)
|   | |-::view-transition-old(clipper)
|   | |-::view-transition-new(clipper)
|   |-::view-transition-group(auto)
|   | |-::view-transition-image-pair(auto)
|   |   |-::view-transition-old(auto)
|   |   |-::view-transition-new(auto)
|   |-...

Essentially, ::view-transition-groups for the items are siblings of ::view-transition-image-pair(clipper)

Now, to achieve the desired effect we need to put a clip on ::view-transition-group(clipper). This works well in a limited number of cases. The problem happens once you have a border (with maybe a rounded clip) on the original clipper element. Because the ::view-transition-group(clipper) element is sized to be the border box of the original element, and the fact that border itself is baked into ::view-transition-{old/new}(clipper), we end up in a situation where it isn't trivial to properly clip the nested groups and also not clip the border. The solution is possible, but not ergonomic where one has to copy the border to the group pseudo, and do some sizing/offset magic to account for the fact that we're sized to the border box.

@bramus put together a demo here:
https://codepen.io/bramus/full/EaxvMXG/11b9fcbe8ebf42034110d3b486db037f

One improvement we can make is to introduce a new pseudo element ::view-transition-group-container (name tbd) that's sized to the padding box of the original element (I think that's the right clipping box or is it content box?) and hosts the nested groups:

:root
|-::view-transition
| |-::view-transition-group(clipper)
|   |-::view-transition-image-pair(clipper)
|   | |-::view-transition-old(clipper)
|   | |-::view-transition-new(clipper)
|   |-::view-transition-group-container(clipper)
|   | |-::view-transition-group(auto)
|   | | |-::view-transition-image-pair(auto)
|   | |   |-::view-transition-old(auto)
|   | |   |-::view-transition-new(auto)
|   | |-...

With that, adding a clip to ::view-transition-group-container(clipper) does not clip the captured box decorations of the original element, and there's less math required.

Cons:

  • The clip won't be trivial with corner shape changes
  • This clip won't clip other captured content from the original element that is not itself view transition named
  • There are likely other issues, but @bramus's demo has an example of what this may look like and it seems a bit more ergonomic.

/cc @noamr @nt1m @bramus @jakearchibald

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Regular agenda

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions