w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.37k stars 642 forks source link

[css-contain-2] Consider forcing layout on content that is skipped when querying it on an element with content-visibility #9675

Open nt1m opened 7 months ago

nt1m commented 7 months ago

On https://rishi.app/blog/using-dotenv-vault-with-edgio-and-nuxt-js/

$("ul").getBoundingClientRect() will return a zero height, but will return the correct height when scrolled into view. ul has content-visibility: auto so only its contents are skipped, so lazy layout doesn't apply here unfortunately.

It seems a bit unexpected, especially when the spec says values queried from script should be consistent.

cc @rwlbuis @vmpstr @smfr @nmoucht

vmpstr commented 7 months ago

The problem here is that it's not the "skip the contents" part that is making the element be 0 height, it's the fact that when not relevant to the user content-visibility: auto applies size containment (among other things).

You can see a similar result by removing content-visibility: auto and replacing it with contain: size -- the height becomes 0 even if its contents are laid out.

getBoundingClientRect and other things that force rendering to be finished do not remove contain: size, they only ensure no lazy rendering optimization is script visible

nt1m commented 7 months ago

@vmpstr I'm confused, if this is caused by size containment, why does scrolling into view give the right dimensions? I indeed see that if you change all the affected elements from c-v: auto to contain: size then the ul does return zero height, but it is not the case if you only change the ul itself.

Loirooriol commented 7 months ago

If you scroll it into view it no longer skips its contents so it loses size containment.

nt1m commented 7 months ago

Is it how it's supposed to work? Dynamic changes in containment feels inefficient to me

vmpstr commented 7 months ago

Size containment is the only containment that toggles (paint layout and style always apply), but yeah that's the way it works. Size containment is important for us to be able to optimize layout -- since the size of the box would not depend on the sizes of its descendants. We'd ideally keep size containment unconditionally, but it makes for tough authoring since developers need to specify sizes of their content.

Instead, we decided to do the automatic toggle, and coupled with contain-intrinsic-size auto, the effective size of the box should stay relatively stable.

vmpstr commented 7 months ago

This also keeps the sizing of content-visibility element less magic (IMHO): it just lays out with or without size containment depending of whether it's relevant, without the need to reference whether the descendants are laid out or not