-
Notifications
You must be signed in to change notification settings - Fork 26
layout instability spec needs to clarify whether (and which) unpainted nodes are considered or not #61
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
CC @npm1 and @mattwoodrow I suspect the current Chrome behavior on my testcase (e.g. the strange behavior-difference between Ideally, I think the spec should allow UAs to exclude unpainted content from contributing to layout shift, because: Ideally, the spec should encode this allowance in such a way as to also allow for variations between browser rendering engines on what things they bother to consider painted vs. unpainted. It should also allow for the possibility of new CSS features (like |
Yea, painting invisible things is always tricky... In this case, I agree that one possible solution is to say that the above (plus potentially others) may be considered or ignored for the purposes of layout shift. Another possibility is that the above elements really shouldn't trigger layout shifts, and the fact that opacity:0 ones do would be a bug in the Chrome implementation (probably should add WPTs for this). But nonetheless due to the hairy nature of these kinds of elements we should clarify either way. Thanks for pointing out this problem and for the investigation into the Chrome behavior :) |
Thanks for raising this. I think we should, at a minimum, update the spec to say that a node in a visibility:hidden subtree is not considered unstable. Probably we should also update the definition of visual representation to say that ancestor clips are applied (I think Chrome does this as part of its coordinate mapping). For opacity:0 it is less clear that we can efficiently exclude it in all cases (e.g. compositing) and I would be ok with allowing the UA to decide. |
Nit: for this hypothetical spec text, you probably really would want Subtrees aren't really relevant for
Cool - it would be great if there was some spec text (e.g. "For nodes that generate boxes that are not painted for whatever reason..." Not sure what the best spec terminology is to use there, but I think that would be the rough qualifier for this category. |
Sorry for the delay replying here, but coming back to this, is the proposal to allow user agent to decide either way for content affected by |
Sure, I think I'd be OK with leaving it up to UA discretion for those One other loop to close here, though -- Chrome does also disagree with the spec on the "contain:paint and zero size" scenario. (The spec considers movement inside of such an element as contributing to shift, but Chrome does not, last time I checked.) That should probably either be considered a Chrome bug (and tracked as such), or it needs a spec exception of some sort (whether general or specific). |
One other update: it seems Chrome's behavior has changed here, such that all the cases in my fiddle (discussed in the original comment here) do all now report a layout shift. I'm testing Chrome 87.0.4259.3 (Official Build) dev (64-bit) on Ubuntu 20.04. |
Hmm interesting, per your previous comment it seems that the latest change is more in line with the spec, even if in practice it looks like the results are less desirable. I filed https://bugs.chromium.org/p/chromium/issues/detail?id=1127474 to discuss but it sounds like the current behavior is spec compliant? |
Yes, I think Chrome's implementation has become spec complaint on the cases that I'd brought up (since all of these cases "generate boxes", which means their movements should be considered as contributing to layout shift, and now Chrome does seem to consider them.) |
(Still: I think I would prefer for the spec to allow for some flexibility on this - the approach that @mattwoodrow and I were envisioning would need to exclude some of these unpainted cases, at least. But perhaps this can fall under the umbrella of user agents "compromis[ing] precision in the interest of calculation efficiency".) |
Are there any unexpected consequences of allowing different behaviour between UAs here? For example, if an author optimizes their page using a UA that doesn't penalize invisible content, are there downsides for them still receiving a poor score in a different UA? |
You mean flexibility on all of the testcases mentioned in the original issue, or which of them? The spec currently says all of them should trigger shifts. We could keep the existing text and add some text saying the user agent may choose to ignore shifts of content that they deem invisible? It's hand-wavy, so an alternative would be to decide which of those are important to make flexible and write something specific to those, WDYT?
There wouldn't be downsides to the user experience given that they are invisible shifts. I'm more concerned about developers wasting time trying to fix invisible shifts or losing trust in the metric because it reports them. |
Some of them. In particular, I think We're not settled on a specific implementation approach or timeline yet, though, for what it's worth.
I'm conflicted, but I think I like this. (If this were a purely opt-in feature, I'd feel much more in favor of strictly defining the behavior, without regard for computational cost. But since it's not opt-in -- browsers must collect the first 150 samples for all pageloads per #52 -- that means we have to be careful about requiring any computations whose value is dubious.)
This is a good point & is something that we'll definitely need to weigh whenever taking advantage of a "The UA may choose..." route. Given that it seems this metric will impact search rankings, it's clear that web developers will largely have search ranking in mind, and they'll expect their browser to be at least as strict as the web-spidering-UA that's used for search ranking computations. Otherwise they might optimize to a threshold that they think is satisfactory (according to their local tools), only to find out later that they're still being penalized (according to the search engine that they're optimizing towards). So for cases that web developers are likely to stumble across, I think we need to be very careful about diverging. But for more extreme edge cases where there's little user benefit to any particular behavior, I'd think we could diverge if it helps simplify the implementation. |
I expect Google will use a Blink-based UA to do that, which means that the Google Search business is favoring Chrome through its page ranking. It seems to me there is a feedback loop between Google Search and Chrome here that risks penalizing other browser vendors. |
Taking a step back, no one is trying to penalize any vendor. That would be a counter productive strategy for everyone involved. The goal is to help developers identify and improve bad user experiences on their pages. The fact that Google Search will include CLS as one of its many signals is, yes, an added incentive for site owners, but not the goal or reason for why we want to encourage developers to measure and improve their pages. To that end, we should optimize the metric to ensure that it both (a) best reflects the perceived user experience and (b) does not create unnecessary work for developers, i.e. strive for consistency between how we measure and what we surface. If this all sounds obvious then, great... that’s why we’re working together in this forum to come up with an interoperable and sensible solution. Back to the matter at hand... in the case where invisible content shifts and is counted as a penalty, we’re failing both of the above criteria. If the shift is not visible to the user, we shouldn’t penalize the site. So for all of the above cases where we agree we can implement and track, we should specify that the invisible content should not produce a shift. For the remainder, we should leave it up to the user agent instead of specifying that invisible content should produce a shift. |
If it's useful here's a very simple test case where opacity 0 leads to a layout shift but the user experience if actually fine. I'd vote for elements with opacity 0 to not cause layout shifts. |
Chrome has updated layout shifts to ignore Looks like it will be released in Chrome 89. |
That's right, we have updated the implementation with https://chromium-review.googlesource.com/c/chromium/src/+/2591907 as well as https://chromium-review.googlesource.com/c/chromium/src/+/2611555. We need to update the spec to reflect these changes. |
We should not consider a node unstable if its computed visibility or opacity are hidden/0 in the frame or previous frame. Addresses #61
This CL tests that there are not shifts reported when an element: * Changes from visibility:visible to hidden * Changes from Opacity 1 to 0 Relevant issue: WICG/layout-instability#61 Change-Id: I0174d37673f34ca3adeeb66b238d4c79edf62e45
So looking at the initial report, I think we've clarified that some of the invisible cases should not be reported - this would be subject to debate later on if another implementor finds it too costly to keep track of. So we decided on all except the |
This CL tests that there are not shifts reported when an element: * Changes from visibility:visible to hidden * Changes from Opacity 1 to 0 Relevant issue: WICG/layout-instability#61 Change-Id: I0174d37673f34ca3adeeb66b238d4c79edf62e45 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2653974 Reviewed-by: Steve Kobes <skobes@chromium.org> Commit-Queue: Nicolás Peña Moreno <npm@chromium.org> Cr-Commit-Position: refs/heads/master@{#848520}
This CL tests that there are not shifts reported when an element: * Changes from visibility:visible to hidden * Changes from Opacity 1 to 0 Relevant issue: WICG/layout-instability#61 Change-Id: I0174d37673f34ca3adeeb66b238d4c79edf62e45 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2653974 Reviewed-by: Steve Kobes <skobes@chromium.org> Commit-Queue: Nicolás Peña Moreno <npm@chromium.org> Cr-Commit-Position: refs/heads/master@{#848520}
I think we may want to change this, as I mentioned on http://crbug.com/1099350. Should we leave this issue open for that, or file a new one? |
This CL tests that there are not shifts reported when an element: * Changes from visibility:visible to hidden * Changes from Opacity 1 to 0 Relevant issue: WICG/layout-instability#61 Change-Id: I0174d37673f34ca3adeeb66b238d4c79edf62e45 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2653974 Reviewed-by: Steve Kobes <skobes@chromium.org> Commit-Queue: Nicolás Peña Moreno <npm@chromium.org> Cr-Commit-Position: refs/heads/master@{#848520}
I suppose it depends on what you mean by empty. In the example, the div does contain content, it is just clipped by the |
…ble to visible, a=testonly Automatic update from web-platform-tests [LayoutInstability] Add tests for invisible to visible This CL tests that there are not shifts reported when an element: * Changes from visibility:visible to hidden * Changes from Opacity 1 to 0 Relevant issue: WICG/layout-instability#61 Change-Id: I0174d37673f34ca3adeeb66b238d4c79edf62e45 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2653974 Reviewed-by: Steve Kobes <skobes@chromium.org> Commit-Queue: Nicolás Peña Moreno <npm@chromium.org> Cr-Commit-Position: refs/heads/master@{#848520} -- wpt-commits: 2f23ceeb5c7b64abfce343e0f96c73c7c11e97ba wpt-pr: 27357
…ble to visible, a=testonly Automatic update from web-platform-tests [LayoutInstability] Add tests for invisible to visible This CL tests that there are not shifts reported when an element: * Changes from visibility:visible to hidden * Changes from Opacity 1 to 0 Relevant issue: WICG/layout-instability#61 Change-Id: I0174d37673f34ca3adeeb66b238d4c79edf62e45 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2653974 Reviewed-by: Steve Kobes <skobeschromium.org> Commit-Queue: Nicolás Peña Moreno <npmchromium.org> Cr-Commit-Position: refs/heads/master{#848520} -- wpt-commits: 2f23ceeb5c7b64abfce343e0f96c73c7c11e97ba wpt-pr: 27357 UltraBlame original commit: caa4ac2a430122150240c6ba405185b9bfaf20df
…ble to visible, a=testonly Automatic update from web-platform-tests [LayoutInstability] Add tests for invisible to visible This CL tests that there are not shifts reported when an element: * Changes from visibility:visible to hidden * Changes from Opacity 1 to 0 Relevant issue: WICG/layout-instability#61 Change-Id: I0174d37673f34ca3adeeb66b238d4c79edf62e45 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2653974 Reviewed-by: Steve Kobes <skobeschromium.org> Commit-Queue: Nicolás Peña Moreno <npmchromium.org> Cr-Commit-Position: refs/heads/master{#848520} -- wpt-commits: 2f23ceeb5c7b64abfce343e0f96c73c7c11e97ba wpt-pr: 27357 UltraBlame original commit: caa4ac2a430122150240c6ba405185b9bfaf20df
…ble to visible, a=testonly Automatic update from web-platform-tests [LayoutInstability] Add tests for invisible to visible This CL tests that there are not shifts reported when an element: * Changes from visibility:visible to hidden * Changes from Opacity 1 to 0 Relevant issue: WICG/layout-instability#61 Change-Id: I0174d37673f34ca3adeeb66b238d4c79edf62e45 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2653974 Reviewed-by: Steve Kobes <skobeschromium.org> Commit-Queue: Nicolás Peña Moreno <npmchromium.org> Cr-Commit-Position: refs/heads/master{#848520} -- wpt-commits: 2f23ceeb5c7b64abfce343e0f96c73c7c11e97ba wpt-pr: 27357 UltraBlame original commit: caa4ac2a430122150240c6ba405185b9bfaf20df
…ble to visible, a=testonly Automatic update from web-platform-tests [LayoutInstability] Add tests for invisible to visible This CL tests that there are not shifts reported when an element: * Changes from visibility:visible to hidden * Changes from Opacity 1 to 0 Relevant issue: WICG/layout-instability#61 Change-Id: I0174d37673f34ca3adeeb66b238d4c79edf62e45 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2653974 Reviewed-by: Steve Kobes <skobes@chromium.org> Commit-Queue: Nicolás Peña Moreno <npm@chromium.org> Cr-Commit-Position: refs/heads/master@{#848520} -- wpt-commits: 2f23ceeb5c7b64abfce343e0f96c73c7c11e97ba wpt-pr: 27357
I think the newish This commit added some text that's conditioned on whether "...the computed value of the opacity property for N is not equal to 0", but I don't think that's the right condition. If you set So when asking whether a particular node is painted, it's not sufficient to just reason about the node's own With that clarified, I think this issue could probably be closed, from my perspective. Thanks! |
Ah yea, I don't know why I thought that computed value would already account for inheritance. Will fix! |
When determining whether the node can be considered unstable, we need to consider not just the node but also its ancestors, since computed value does not account for inheritance. Fixes #61
Right now, the layout instability spec officially considers a moved element as contributing to instability if the element "generates one or more boxes", as defined here: https://wicg.github.io/layout-instability/#visual-representation
However, this may not be practical for implementations, and it seems to be inconsistent with how the feature is implemented in Chrome.
Consider for example this testcase, which has an element with
visibility:hidden
that gets shifted (via the insertion of another node before it): https://jsfiddle.net/yqr570ex/In Chrome 84, this testcase does NOT trigger a reported Layout Shift right now, even though the visibility:hidden element definitely "generates a box". I've included a few other notable CSS classes that you can set on the container for the shifted element (the thing with
id="giveMeAClass"
). And when the shifted element's parent has...visibility:hidden
: it does NOT trigger a layout shift report in Chrome (as noted above)contain:paint
and zero size (i.e. fully clipped): it does NOT trigger a layout shift report in Chrome....vs.:
opacity:0
: it DOES trigger a layout shift report in Chrome.contain:paint
and a small nonzero size (i.e. almost-fully clipped, nothing actually painted): it DOES trigger a layout shift report in Chrome.I think both the spec & Chrome need to be updated to have a coherent story on which of these should be considered. The final one here (contain:paint and small nonzero size) makes sense, but the other three seem like they should be consistent & should be clearly defined by the spec; right now, the spec seems like it would call for them all to trigger layout shifts.
The text was updated successfully, but these errors were encountered: