Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-view-transitions-1] content-visibility: auto elements are relevant to the user during a transition #7874

Closed
khushalsagar opened this issue Oct 12, 2022 · 8 comments
Labels
css-view-transitions-1 View Transitions; Bugs only

Comments

@khushalsagar
Copy link
Member

content-visibility: auto allows the user agent to minimize the rendering cost for elements which are not relevant to the user. There are multiple subtle interactions this optimization has with View transitions.

  1. Identifying elements with a valid page-transition-tag (and other constraints) requires all elements to have up to date style (see logic here). Offscreen elements can also participate in a transition since the transition might bring them onscreen. So content-visibility: auto shouldn't prevent discovery of a tagged element.

    The default behaviour would be for the transition to force style update for the whole DOM tree to discover tagged elements. We can add an option going forward (new contain keyword?) for the author to indicate that a sub-tree doesn't have tagged elements.

  2. If an element with content-visibility: auto is tagged, it becomes relevant to the user.

  3. If an element with content-visibility: auto has a descendant which is tagged, the element becomes relevant to the user. This is because we need to layout/paint the tagged element to render it in its corresponding replaced pseudo-element.

  4. If an element with content-visibility: auto has an ancestor which is tagged then we have 2 cases:

    • If that ancestor is the root element then content-visibilty: auto can continue to apply. This is because the root snapshot is clipped to the viewport. See [css-shared-element-transitions-1] Define transitions over changing viewport #7859 for details.
    • If that ancestor is a non-root element then the content-visibility: auto node becomes relevant to the user. This is because snapshots for non-root elements are painted in their entirety (modulo hardware constraints).

@vmpstr to validate the summary.

@khushalsagar khushalsagar added the css-view-transitions-1 View Transitions; Bugs only label Oct 13, 2022
@khushalsagar
Copy link
Member Author

We had an offline discussion about this, summarized below. There are 2 different points to resolve for this issue:

  1. If an element is participating in a transition, any element in its sub-tree (which has c-v: auto) should become relevant to the user. This makes sense given that the tagged element will be painted into a snapshot. This snapshot's position and scale is animated during the transition (by the pseudo-element its drawn in). So all its content (including the c-v: auto elements) could be in the viewport.

    Given that the snapshot for all non-root elements paints the entire DOM tree underneath, it'll make all c-v: auto elements underneath a non-root tagged element relevant to the user. It's only the root (for which the snapshot is clipped) which can have c-v: auto elements underneath that are clipped out of the snapshot and hence don't need to be made relevant to the user.

    Proposed Resolution: An element with content-visibility: auto is relevant to the user if it is painted into self or an ancestor's snapshot during a transition.

  2. Deciding which elements participate in a transition requires resolving style on all DOM elements so the computed value of page-transition-tag property is known. This forces resolving at least style for elements with c-v: auto. That defeats the purpose of the optimization. There are 2 choices:

    • By default force style resolution on the whole DOM to find all tagged elements so c-v: auto doesn't influence whether a tag works. The developer will have no way to retain the optimization beyond temporarily adding content-visibility: hidden if they don't need tags under a DOM subtree to be discovered. We could add a contain: view-transition for the developer to directly express that intent.

    • Elements under a c-v: auto element which is not already relevant to the user can't participate in a transition. "Relevant to the user" can be different across browsers since margin around viewport is user-agent defined. If the developer wants elements to always be discovered they can switch to c-v: visible for the transition.

    Proposed Resolution: When traversing the DOM to discover tagged elements only visit elements relevant to the user. Updates step 4 here and here changes to "For each element and pseudo-element connected to document and relevant to the user".

@atanassov atanassov added this to View transitions in October 26 meeting Oct 25, 2022
@astearns astearns moved this from View transitions to Overflow items in October 26 meeting Oct 26, 2022
@jakearchibald
Copy link
Contributor

What happens if you call getBoundingClientRect on an element within a hidden content-visibility: auto region?

If that gives a result as if the element is not-rendered, then I think View Transitions should also treat the element as not-rendered.

@khushalsagar
Copy link
Member Author

getBoundingClientRect is fine for the element with content-visibility: auto since that element has been styled/laid out. But if you call it for one of its descendants, it forces a style/layout and causes the browser to do work it had optimized out.

@jakearchibald
Copy link
Contributor

Huh, that's surprising.

@jakearchibald
Copy link
Contributor

jakearchibald commented Nov 8, 2022

Triggering a potentially large layout in the middle of a page switch is definitely a bad thing. I'm kinda surprised that content-visibility de-opts when querying particular layout info.

We talked about another feature elsewhere WICG/view-transitions#84, that changed the behaviour of elements outside the viewport. If you opt-in to treating outside-viewport elements as "not rendered", then you avoid the heuristic behaviour of content-visibility.

Thinking it through, I still think we have the right default - transition things from their original position. That works well for most use-cases.

It doesn't work well for cases like a header transition. If the header can be scrolled away 1000s of pixels, having it transition back to the top is a bad transition. You can work around this with JS pretty easily by tagging the header dynamically if it's in the viewport, but a high-level way of doing that seems reasonable, but I don't think we need it for MVP.

If a grid of items is transitioning in a way that makes them shorter, that may result in additional rows entering the viewport. In this case you really want them to animate from their original positions, even though they were outside the viewport.

@jakearchibald
Copy link
Contributor

I understand content-visibility a bit better now. Specifically: the changes in the container size are observable, but the layout skipping of the content is not supposed to be observable.

So, I guess we're talking about doing something different than that for view transitions? Yeah, that doesn't seem great, but I don't think there's a better option.

@khushalsagar
Copy link
Member Author

I guess we're talking about doing something different than that for view transitions

Yes. getBoundingClientRect will force style/layout for a node which is "not relevant to the user" and is in locked state. One difference between this and view transitions is that the forced style/layout only happens if the developer queries this info from script.

With view transitions if we take the same pattern we'll have to force style resolution for the entire DOM even if there is no node with a view-transition-name under a content-visibility: auto node. There also won't be a way for the developer to indicate that no such node exists and the browser can avoid the style walk without an explicit property (like contain: view-transition-name).

That's why I'm more inclined to skip discovering view-transition-names under a DOM node if its not relevant to the user. And letting authors use content-visibility: visible if they want such names to be discovered deterministically.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-view-transitions-1] content-visibility: auto elements are relevant to the user during a transition, and agreed to the following:

  • RESOLVED: elements under content-visiblity:auto element that skip its contents are not eligible to participate in view transition
The full IRC log of that discussion <fantasai> Topic: [css-view-transitions-1] content-visibility: auto elements are relevant to the user during a transition
<fantasai> github: https://github.com//issues/7874
<fantasai> vmpstr: content-visibility: autho not user relevant, they don't update rendering, so we can't tell if they've been tagged with a view transition name
<flackr> q+
<fantasai> vmpstr: so we'd like to say that such elements that are not relevant to the user can't participate in the view transition because they're far enough offscreen
<fantasai> flackr: my preference was element can participate, because could move on screen, but none of its descendants
<fantasai> vmpstr: sorry, meant the subtree elements cannot be detected as participating in this transition
<Rossen_> ack flackr
<fantasai> vmpstr: content-visiblity: auto only affects content
<fantasai> flackr: with that correct, good with that
<fantasai> Rossen_: proposal?
<fantasai> vmpstr: elements under content-visiblity:auto element that skip its contents cannot be discovered as participating in view transition
<flackr> +1
<fantasai> s/cannot/are not eligible to be/
<fantasai> florian: seems reasonable
<fantasai> +1
<fantasai> Rossen_: objections to resolving on that edited proposal?
<fantasai> RESOLVED: elements under content-visiblity:auto element that skip its contents are not eligible to participate in view transition

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-view-transitions-1 View Transitions; Bugs only
Projects
No open projects
October 26 meeting
Overflow items
Development

No branches or pull requests

4 participants