Skip to content

[css-view-transitions-1] Handling cases where transition constraints are broken mid transition #7882

Closed

Description

@khushalsagar

View transitions require a bunch of constraints to be satisfied by tagged elements listed here:

If any of the following is true:

usedTransitionTags [contains](https://infra.spec.whatwg.org/#list-contain) transitionTag.

element is not element’s [root](https://dom.spec.whatwg.org/#concept-tree-root) and element does not have [layout containment](https://drafts.csswg.org/css-contain-2/#layout-containment).

element is not element’s [root](https://dom.spec.whatwg.org/#concept-tree-root) and element allows [fragmentation](https://drafts.csswg.org/css-break-4/#fragmentation).

This state can also change mid transition. The simplest thing is to skip the transition in this case.

Activity

  1. khushalsagar commented on Oct 18, 2022

    @khushalsagar
    MemberAuthor

    Summary from offline discussion: It makes sense to abort the transition if per element constraints are broken, i.e., no layout containment or the element allows fragmentation. But detecting if the computed value of tags on all DOM elements has changed (so we now have duplicate tags etc.) adds more computation work. And that work would be to detect a developer bug and abort the transition. So not worth it.

    Proposed Resolution: If constraints on elements participating in a transition become unsatisfied after a transition is running, the transition is aborted. Set of tagged elements participating in a transition is not re-computed after animations have started.

  2. khushalsagar commented on Nov 15, 2022

    @khushalsagar
    MemberAuthor

    One constraint (which I missed above) is that an element participating in a transition must generate a box (can't be display: none).

    When walking through the DOM to identify named elements, we ignore DOM elements which don't generate a box (as if they had view-transition-name:none). See spec text here: "If transitionName is none, or element is not rendered, then continue."

    A change in this state (such that the element no longer generates a box) should also skip the transition.

  3. jakearchibald commented on Dec 1, 2022

    @jakearchibald
    Contributor

    Another option for an element changing to display: none (or being removed from the DOM):

    If there's a ::view-transition-old: Remove the ::view-transition-new from that pair, and set the end position & size to the captured element's position & size. This means the animation would continue as if there was no captured element in the new state.

    If there isn't a ::view-transition-old: Remove the ::view-transition-group.

    If the element is reshown during the transition: Do nothing. It can't come back.

  4. fantasai commented on Dec 6, 2022

    @fantasai
    Collaborator

    @jakearchibald @khushalsagar Can you summarize what question you want to ask the WG? It's okay to have multiple options to consider (or even an open-ended question), but since there's been several threads of conversation I just want us collect in one comment everything we want the CSSWG to consider. :)

  5. jakearchibald commented on Dec 6, 2022

    @jakearchibald
    Contributor

    In a transition group that has a 'new' component (as in, the end state of the transition is linked to a renderable element in the document), that element controls the final width/height/position of the ::view-transition-group and the natural size and image of the ::view-transition-new.

    If that element changes layout or appearance, the ::view-transition-group and ::view-transition-new is updated.

    But, what should happen if, mid-transition:

    • That element is no longer renderable (eg display: none or removed from the document)
    • That element becomes renderable again

    And does the behaviour change depending on if the ::view-transition-group has a ::view-transition-old (as in, it's transitioning 'from' a captured element)?

    The following options assume that the linking of source elements to ::view-transition-new via their view-transition-name is performed once. As in, changes to elements' view-transition-name do not impact the current transition.

    It also assumes that "the element is no longer renderable" check is performed in the render steps, when the view transition currently updates its state per frame.


    Option 1: Skip the transition

    If the transition starts with a ::view-transition-new, then it's required that the source element is capturable until the end of the transition. Otherwise, the remainder of the transition is skipped.

    Option 2: Adapt the transition, no backsies

    If the element is no longer renderable:

    If the group has a ::view-transition-old, then the group's associated ::view-transition-new is removed from the group. The size & transform of the ::view-transition-group becomes the same as its 'from' keyframe (meaning it stays in the same size and position as the old element).

    This puts the ::view-transition-group into a state as if the ::view-transition-new wasn't there in the first place.

    However, this would cause ::view-transition-old:only-child to match, and which could cause new animations to start mid-way through the transition.

    If the group does not have a ::view-transition-old, then the ::view-transition-group is removed.

    If the element becomes renderable again, no action is taken.

    Option 3: Adapt the transition, with backsies

    If the element is no longer renderable, the group's associated ::view-transition-new becomes 0x0, transparent.

    If the group has a ::view-transition-old, the size & transform of the ::view-transition-group becomes the same as its 'from' keyframe (meaning it stays in the same size and position as the old element).

    This is mostly as if ::view-transition-new wasn't there in the first place, but not quite.

    If the group does not have a ::view-transition-old, the size & transform of the ::view-transition-group becomes 0x0, with no transform (placing the group in the top-left of the snapshot viewport).

    If the element becomes renderable again, the state is updated again, allowing the element to reappear.


    The two "adapt the transition" options seem to have weird trade-offs, so I think I'm happiest with option 1.

  6. khushalsagar commented on Jan 3, 2023

    @khushalsagar
    MemberAuthor

    Thanks for the summary @jakearchibald. +1 to option 1. Toggling of this state mid-transition seems like a bug rather than a pattern the developer would need for a particular UX.

  7. khushalsagar commented on Jan 10, 2023

    @khushalsagar
    MemberAuthor

    Reiterating the proposed resolution : "If constraints on new elements participating in a transition become unsatisfied mid-transition, the transition is aborted."

    Note that this issue is limited to the behaviour if the constraints are changed by the developer during the transition. The exact constraints are already in the spec with active discussion on clarifying/relaxing them:

  8. astearns commented on Jan 24, 2023

    @astearns
    Member

    Since there is a clear resolution and agreement here in the issue, let’s try making this an async resolution.

    The CSSWG will automatically accept this resolution one week from now if no objections are raised here. Anyone can add an emoji to this comment to express support. If you do not support this resolution, please add a new comment.

    proposed resolution : If constraints on new elements participating in a transition become unsatisfied mid-transition, the transition is aborted.

  9. added a commit that references this issue on Jan 24, 2023
  10. 12 remaining items

  11. added a commit that references this issue on Mar 7, 2023
    2bbe632
  12. added a commit that references this issue on Feb 12, 2024
    d74719a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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