Skip to content

[css-sizing-4][css-contain-2] Revisiting auto-sizing when size-containment applies #5668

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

Closed
vmpstr opened this issue Oct 27, 2020 · 13 comments
Closed
Labels
css-contain-2 Current Work

Comments

@vmpstr
Copy link
Member

vmpstr commented Oct 27, 2020

The content-visibility: auto value causes the user agent to apply size-containment under certain conditions (generally, when content is outside of the viewport)

There is also another property that was added, contain-intrinsic-size, which helps with adoption of content-visibility: auto. It allows the developer to specify a "placeholder" size when size-containment is present.

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.

My proposal is that we consider adding another value for contain-intrinsic-size, which would use known intrinsic size at the time size containment was last added, with a fallback value if size containment was present before the initial layout of the contents. It would basically freeze the intrinsic size when containment is added and use that.

The syntax would be something like the following:
contain-intrinsic-size: auto 0 auto 100px
which would mean:

  • If size containment was present before the initial layout of the contents, then this is the same as contain-intrinsic-size: 0 100px
  • If size containment was added after the initial layout of contents, then this is the same as the intrinsic size of contents at the time that size containment was last added

For context, this is similar to a previous proposal, which was rejected: #1043.
I think this proposal is sufficiently different in that we already have the "use this (intrinsic) size when size containment is present" property. The addition is just to prefer using the real intrinsic size if it is available at the time size containment applies.

One con of the approach is that the timing of when to measure intrinsic size isn't clear. When size containment applies, we should read off the last computed intrinsic size. However, this value could be different depending on when the UA decides to update the intrinsic size. So this may cause some observable implementation differences.

@chrishtr
Copy link
Contributor

/sub

@fantasai fantasai added the css-contain-2 Current Work label Oct 27, 2020
@cbiesinger
Copy link

Hmm, it seems like it will be very tricky to get interop on this one, depending how it's specified.

@vmpstr
Copy link
Member Author

vmpstr commented Jan 7, 2021

Putting this on the agenda mostly to gather feedback about the general direction: Can we have something that 'remembers' the size when size-containment applies

@dholbert
Copy link
Member

Yeah, I'm uneasy about this... If I'm understanding the proposal correctly, it sounds like it introduces a new bit of non-determinism, or at least a dependency on the exact sequence of events (and the timing of layouts) in a way that feels like it goes against how CSS usually works.

@tabatkins
Copy link
Member

I think it introduces no more non-determinism or dependency than animations already introduce, yeah? An animation's start time, and thus its effect on the page at any given moment, depends on when the animation style started applying, which seems identical to the case here.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-sizing-4][css-contain-2] Revisiting auto-sizing when size-containment applies, and agreed to the following:

  • RESOLVED: align the behavior of auto sizing for size-containment with that of resizeObserver
The full IRC log of that discussion <dael> Topic: [css-sizing-4][css-contain-2] Revisiting auto-sizing when size-containment applies
<dael> github: https://github.com//issues/5668
<dael> vmpstr: A little background. We have content-visibility:auto Way it works is when element goes offscreen we add size containment and when it's on screen we remove. Can change the scrollbar size which is undesired. Added contraint-intrinsic-size to manage this. Works great as a placeholder b/c gives some size even when size containment applies.
<dael> vmpstr: Problem is it's hard to know the right size so scrollbar can still jump. When element is on screen as it rolls offscreen browser knows size that would cause scrollbar not to jump. There is a value it oculd take. Broswer knows but it's not exposed
<dael> vmpstr: I think script can get an estimate
<dael> vmpstr: Prop is add an auto qualification to contain-intrinsic-size which is when size containment is first applied and when content has been previously rendered remember that size and use it as the value. Else use placeholder
<dael> vmpstr: Daniel and Christian raised some points that it adds dependency on sequence of steps.
<TabAtkins> q+
<smfr> q+
<dael> vmpstr: Wanted to bring to group. Hoping there's a solution that doesn't involve script. Maybe not this exact proposal, but this is what I have
<dael> TabAtkins: Point about non-determinism about exactly when size is recorded, while technically true it's a cost we eaten with animations. Style depends on exactly when it started so you know how far in animation you are. Since we've eaten that cost for animations I don't see why not here unless we think that was unavoidably broken
<dael> TabAtkins: We should think about htis the same as animation start
<Rossen_> ack TabAtkins
<Rossen_> ack smfr
<TabAtkins> smfr's idea makes sense to me as well
<TabAtkins> it's what you'd get if you did this by hand anyway
<dael> smfr: Slightly different prop is spec this exactly same as resizeObserver. Timing is well defined. Write the spec so you get the same behavior as if you registered a resize on it and that's the same size as you'd get with snapshot
<dael> vmpstr: Good idea. Question is when do we snapshot. If you add size containment and change another style I guess you first process size containment and snapshot at that time?
<dael> smfr: I think you would use size from the most recent event loop steps where your resize observer would have fired and given an answer. Might be loop before a style change that effects containment
<dael> smfr: That's last thing you saw on screen
<dael> vmpstr: Makes sense
<dael> chrishtr: resizeObserver is when content-visbility content is unskipped, right?
<dael> vmpstr: On the contents of the element. On the element itself the observer would still fire
<dael> chrishtr: So a polyfill would put it on the element and when it fires set contain intrinsic size on that. And smfr proposal is do that without any script
<dael> vmpstr: Pretty much. I've seen a polyfill that does that. I'm not sure what to do with padding and margins.
<dael> chrishtr: ResizeObserver allow syou to observe different boxes
<dael> vmpstr: Then yeah
<dael> chrishtr: What if it was independent of content visibility. It restricts to the c-i-s property
<dael> vmpstr: Content visibility was motivation. Proposal is change to contain intrsintic-size to save off the value
<dael> chrishtr: Only do when size containment wasn't present
<dael> vmpstr: Right. And just snapshot at the time size containment starts being applied
<Rossen_> q?
<dael> chrishtr: So if size containment isn't present that size is automatically reflected into contain-intrincis-size used value
<dael> Rossen_: Hearing alignment on prop from smfr to align with resizeObserver. Are we happy with that and then will work on additional details in the issue?
<chrishtr> q+sounds good to me
<dael> Rossen_: Objections to align the behavior of auto sizing for size-containment with that of resizeObserver
<dael> RESOLVED: align the behavior of auto sizing for size-containment with that of resizeObserver

@tabatkins
Copy link
Member

All right, first draft of the c-i-s: auto behavior is in the spec. Whenever ResizeObserver would look for size changes, it records the sizes of c-i-s:auto elements, and c-i-s:auto then uses that size.

Lmk if this looks good? I'm especially uncertain of how to phrase the timing for the ResizeObserver reference.

@vmpstr
Copy link
Member Author

vmpstr commented Feb 4, 2021

I left a couple of comments. Please let me know if you prefer to have the discussion in this issue instead, for posterity

tabatkins added a commit that referenced this issue Feb 5, 2021
…ord sizes until you're already doing the work normally.
@tabatkins
Copy link
Member

Unless it's a very specific nitpick of a line in the comment, I generally prefer comments to go in the issue, as it's easier to keep track of them.


@vmpstr said:

The problem here is for an optimization that content-visibility: auto provides to be effective, we need to ensure that we can skip layout of the contents as soon as we render the element.

You're right; I misremembered what content-visibility:auto did, and thought it applied size containment, meaning we had to get an experimental layout in anyway (and at that point, might as well do it early for all cases). But nope, an element with skipped contents gets size containment; once an "auto" element is not skipped, it lays out without size containment (assuming nothing else is applying it, of course).

So yeah, I definitely could just wait for that layout to happen and start recording the size then; before that (while it's skipped), it just doesn't have a remembered size.


Question: should it forget its last remembered size if it loses contain-intrinsic-size:auto? I presume we don't want to record this information for all elements all the time, so the restriction to only do the recording when c-i-s:auto is on makes sense, but is it better to forget the size when c-i-s:auto no longer applies, or remember it permanently from then on (even tho it won't be used until you set c-i-s:auto again)?

The way the spec is currently written, once an element records a size it keeps it forever, but I'm happy to make it forget (presumably with the same timing?).

@vmpstr
Copy link
Member Author

vmpstr commented Feb 5, 2021

It makes sense for us to forget the size.

I'm thinking from the perspective of an element that has neither size containment nor contiain-intrinsic-size. In this case, it seems wasteful to remember any type of size because nothing really applies here. However, I can then apply size containment, wait a bit, and apply contain-intrinsic-size: auto. I think it's fair to say that we use a placeholder size in that case, not the remembered size. If you agree with that line of reasoning, then I think that generalizes to us forgetting the value once contain-intrinsic-size: auto is removed.

I'm unfamiliar with the details of the CSS timings, but I'd like to point out a case like "remove contain-intrinsic-size: auto. and then add it in the same function without any forced style in between". Here, we would probably not forget the value, right? And if there was a forced style in between, we would forget the value?

@tabatkins
Copy link
Member

If you agree with that line of reasoning, then I think that generalizes to us forgetting the value once contain-intrinsic-size: auto is removed.

Yup, agreed.

I'm unfamiliar with the details of the CSS timings, but I'd like to point out a case like "remove contain-intrinsic-size: auto. and then add it in the same function without any forced style in between". Here, we would probably not forget the value, right? And if there was a forced style in between, we would forget the value?

Yes, since we resolved that recording the size happened at the time resizeobservers are fired, I'm planning on making the forgetting happen at the same time. So if you really want to make sure it's forgotten, you may have to wait a frame.

@vmpstr
Copy link
Member Author

vmpstr commented Feb 5, 2021

Gotcha, this sounds good to me! Thanks

@chrishtr
Copy link
Contributor

@tabatkins any reason not to close this issue? There is #6220, but that's separate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-contain-2 Current Work
Projects
None yet
Development

No branches or pull requests

7 participants