[csswg-drafts] [css-contain][css-sizing] `content-visibility: auto` kinda broken by not using last remembered size with `contain: size` (#7807)

Loirooriol has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-contain][css-sizing] `content-visibility: auto` kinda broken by not using last remembered size with `contain: size` ==
#5668 added `contain-intrinsic-size: auto`, whose purpose was addressing this problem:

> One undesired effect of content-visibility: auto is that the scrollbar thumb tends to jump around when content enters and exits the visibility region. This is due to the fact that we keep adding and removing size containment in order for us to optimize rendering of skipped content. The contain-intrinsic-size property helps, but the size still keeps changing between the "real" intrinsic size and contain-intrinsic-size placeholder. The two sizes are frequently different.

`contain-intrinsic-size: auto` remembers the non-contained size, bringing stability.

Then #6308 restricted using the last remembered size to when the element skips its contents, so basic `contain: size` doesn't use the last remembered size. The reasoning was that the last remembered size can be out of date, so it can be bad to use it for elements which are visible in the screen.

So main cases have stability:

 - An element with `content-visibility: auto` will remember its non-contained size when visible, then if it goes off the screen it will skip its contents and get containment, using that last remembered size. If it comes back into the screen, it will lose containment and its size will be updated, but in common cases this will be the same as the last remembered size.
 - An element with `contain: size` never uses the last remembered size, so it keeps a consistent size regardless of whether it goes off or into the screen.

But imagine this corner case:
 1. An element has `contain-intrinsic-size: auto 100px; content-visibility: auto`
 2. It's visible in the screen, so it doesn't have containment, and its normal size is remembered, e.g. 15px.
 3. Then it gets `contain: size`. It's still not skipping its contents, so it's resized to 100px.
 4. The last remembered size is not updated, since it has size containment.
 5. The element moves off the screen, so it skips its contents, which changes the size into the remembered 15px.
 6. The element moves back into the screen, so it stops skipping its contents, and becomes 100px.

So the behavior is not stable at all! Here you have a [testcase](https://software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E%0A%3Cstyle%3E%0A%23scroll%20%7B%20overflow-y%3A%20scroll%3B%20position%3A%20fixed%3B%20inset%3A%200%3B%20width%3A%20100px%3B%20border%3A%20solid%3B%20%7D%0A%23scroll%20%3E%20div%20%7B%20contain-intrinsic-size%3A%20auto%20100px%3B%20%7D%0A.contain%20div%20%7B%20contain%3A%20size%3B%20content-visibility%3A%20auto%20%7D%0A%3C%2Fstyle%3E%0A%3Cdiv%20id%3D%22scroll%22%3E%3C%2Fdiv%3E%0A%3Cscript%3E%0Avar%20scroll%20%3D%20document.getElementById(%22scroll%22)%3B%0Afor%20(let%20i%20%3D%200%3B%20i%20%3C%2050%3B%20%2B%2Bi)%20%7B%0A%20%20let%20child%20%3D%20document.createElement(%22div%22)%3B%0A%20%20child.textContent%20%3D%20i%3B%0A%20%20scroll.appendChild(child)%3B%0A%7D%0ArequestAnimationFrame(()%20%3D%3E%20requestAnimationFrame(()%20%3D%3E%20%7B%0A%20%20scroll.classList.add(%22contain%22)%3B%0A%7D))%3B%0A%3C%2Fscript%3E), try scrolling from the top to the bottom and viceversa using the mouse wheel. The scrollbar thumb behaves strangely.

It's an edge case since mixing `content-visibility: auto` and `contain: size` is maybe a weird combination, and `contain: size` needs to be delayed in order to have a last remembered size. But should we try to improve it? Some ideas:

 - Change the requirement for using the last remembered size. Instead of skipping the contents, check that `content-visibility` is not `visible`. Size containment will still be needed of course, so the basic case with just `content-visibility: auto` will not be affected.
 - Change the requirement for updating the last remembered size. Instead of not having size containment, check that the element doesn't skip its contents (since the last remembered size will only be used when skipping the contents).

CC @vmpstr, @hamishwillee

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/7807 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Wednesday, 28 September 2022 19:21:18 UTC