Skip to content

Add optimize-scroll-stability guide#633

Draft
knowler wants to merge 10 commits into
mainfrom
knowler/311-optimize-scroll-stability
Draft

Add optimize-scroll-stability guide#633
knowler wants to merge 10 commits into
mainfrom
knowler/311-optimize-scroll-stability

Conversation

@knowler
Copy link
Copy Markdown
Contributor

@knowler knowler commented Apr 23, 2026

Towards #311

This adds the guide for optimize-scroll-stability which uses contain-intrinsic-size (and friends) for content-visibility: auto. I went with the simplest use case as we can include more advanced ones after I/O.

@knowler
Copy link
Copy Markdown
Contributor Author

knowler commented Apr 29, 2026

@malchata do you think the guide should include the following which could affect scroll stability?

  1. Should it cover reflow use cases (e.g. items in a wrapping flex layout). The current guide focuses on height/block-size for intrinsic size. For wrapping layout, an item’s width can affect when subsequent content wraps which in turn can also affect scroll. This can be harder to guess a good intrinsic size for.
  2. Should it over cover advanced use cases like Alex Russell’s which leverages ResizeObserver and IntersectionObserver to set the exact intrinsic size for elements inline.

I guess you could think of the first as problems that arise in two-dimensional layouts. The technique Alex demonstrates is like “what to do when you need the exact intrinsic size, but can’t infer that from the content,” which could be relevant for both one and two dimension situations.

@malchata
Copy link
Copy Markdown
Member

malchata commented May 4, 2026

I would consider an advanced use case as a "nice to have", and the more I think about it, it might be something to land after I/O. ResizeObserver is tricky in part because it runs its callback at a time where it could delay the next frame from being painted. So let's hold off on the advanced stuff for now.

@jamesnw jamesnw linked an issue May 8, 2026 that may be closed by this pull request
7 tasks
@knowler knowler force-pushed the knowler/311-optimize-scroll-stability branch from c36ddcf to 35c484b Compare May 12, 2026 20:11
@knowler knowler marked this pull request as ready for review May 12, 2026 20:34
@rviscomi
Copy link
Copy Markdown
Member

Should it cover reflow use cases (e.g. items in a wrapping flex layout). The current guide focuses on height/block-size for intrinsic size. For wrapping layout, an item’s width can affect when subsequent content wraps which in turn can also affect scroll. This can be harder to guess a good intrinsic size for.

Is there a workaround for this, or is the guidance effectively "make an educated guess and good luck"? Asking as someone who's given up on a content-visibility optimization before for this exact reason, so I would actually be very eager to see this covered if there's anything actionable.

I would almost rather hold off on publishing this until we have more time to smooth over these advanced use cases and rough edges with more guidance. IMO it's fine to tackle that after I/O rather than rush out a more basic version of this guide, which might trip some developers up.

WDYT @knowler @malchata?

Copy link
Copy Markdown
Member

@rviscomi rviscomi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is missing an expectations file

@rviscomi rviscomi requested a review from LeaVerou May 13, 2026 14:28
@knowler
Copy link
Copy Markdown
Contributor Author

knowler commented May 13, 2026

@rviscomi Unless the exact size of the contents is known ahead of time, it’s very difficult to avoid the reflow issues for two-dimensional layouts, since even for good guesses, an error has more significant effects that don’t get smoothed over as well compared to one-dimensional layouts. With that said, if you can leverage more information about the content ahead of time, like a character count, then you could improve your guesses significantly. This is a some what contrived example (since I’m using the same character to fill the items): https://knowler.dev/demos/hO9UCFj?codepen

The more advanced techniques of caching the sizes after an initial layout seem a bit too tricky to include as instructions for an agent, as there could be a lot of contextual variables necessary to factor into that. There’d also be some performance tradeoffs as well.

@LeaVerou
Copy link
Copy Markdown
Collaborator

(Apologies if you got an email with a half-written version of this, I accidentally hit the keyboard shortcut and posted too soon)

My high level concern is that "optimize scroll stability" is in the same vein as "improve text legibility", i.e. not a concrete use case that an agent is likely to search for. It's good guidance, but it's more useful referenced from elsewhere (i.e. like the new guide-skills) instead of expecting it to come up in a use case search.

But the description already kind of hints at the actual use cases:

Keep the page layout, scroll bar, and scroll position as stable as possible as users scroll through content-heavy pages (feeds, dashboards, long lists) where elements transition from hidden to visible.

It just needs flipping: When we're implementing content-heavy pages (feeds, dashboards, long lists), especially lazy loaded, keeping the page layout and scrollbar stable is one of the things that improve user experience. Are there other things? Can we make a guide that's focused on the concerns that one needs to have in mind when implementing these kinds of long lazy loaded feeds? Scroll stability is only one factor. What are the others?

I would suggest:

  • Move the guidance that's the same for all uses of content-visibility and contain-intrinsic-size to a features/ guide and include it here. E.g. the advice about determining good sizes for this is good, and I can't imagine how other uses of contain-intrinsic-size wouldn't benefit from it (but I haven't yet looked at the 6-7 guides we have on these features)
  • Focus this around use cases rather than scroll stability and include only the delta that's different from other uses of these features.

From a quick look, we also repeat guidance about how to pick a good size in performance/efficient-background-processing and in performance/defer-rendering-heavy-content:

  • 'auto' is optional and enables the browser to remember the actual size
    once rendered. It must be paired with a value to be used for
    the first render.
  • 'none' tells the browser not to apply any intrinsic width to this element.
    It can be used for either the height or the width value.
  • '500px' is the estimated height of this element. This can be any valid
    CSS value. Replace it with the expected height of your
    component.

Whereas in other places where contain-intrinsic-size is mentioned, it would benefit from this guidance, but it isn't there. E.g. the CSS guide:

  • Always pair content-visibility with contain-intrinsic-size to prevent scrollbar jumps (CLS).

Code Example: Render Optimization

.large-section {
  content-visibility: auto;
  contain-intrinsic-size: auto 800px;
}

.popover-reveal {
  /* Allow discrete animations for display transitions */
  transition: display 0.2s allow-discrete;
}

Demo: It's very hard to see what the demo is demonstrating. Commenting content-visibility and contain-intrinsic-size out seems to produce no difference. Also note that scroll anchoring makes the baseline behavior better (though that only affects scroll position, not size). I think it's because all 1000 items are rendered synchronously in one for loop, including their contents.

Last, there's a section at the start with reference-style docs — these shouldn't be needed, this hasn't changed recently and is not super brand new.

(@rviscomi one caveat about this review is that that like I said, perf-related things are not my forte, so I can review what's here, but I'm not the right person to tell you what's missing, if anything!)

Comment on lines +21 to +30
- `contain-intrinsic-size` is a shorthand for `contain-intrinsic-width` and `contain-intrinsic-height`.
- `contain-intrinsic-block-size` and `contain-intrinsic-inline-size` are logical variants of the longhand properties.

The value syntax for the longhand properties is as follows:

- `none` means the element has no intrinsic size for the respective dimension.
- A `<length>` value can be provided to set the intrinsic size.
- `auto <length>` can be provided to set the intrinsic size when it is unknown, otherwise, it will use the last known size of the contents while skipped for rendering.

The default value is `auto none` which means initially there will be no intrinsic size for the contents, but it will use the last known size once that becomes available.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads like reference documentation for contain-intrinsic-size, which the model shouldn't need (the property is Baseline Widely Available, so its syntax is well within its training data)

@knowler
Copy link
Copy Markdown
Contributor Author

knowler commented May 13, 2026

@LeaVerou Thank you for the review! I agree that including this guidance along with content-visibility: auto is a good idea — as I was just writing the expectations that became apparent. Also, TIL about scroll anchoring!

@rviscomi Does it seem like a good idea to defer this guide until after I/O? Perhaps before then, there could be some minor additions to the CSS skills that suggest almost always pairing content-visibility: auto with contain-intrinsic-size, as Lea suggested?

@LeaVerou
Copy link
Copy Markdown
Collaborator

@rviscomi Does it seem like a good idea to defer this guide until after I/O? Perhaps before then, there could be some minor additions to the CSS skills that suggest almost always pairing content-visibility: auto with contain-intrinsic-size, as Lea suggested?

We already have this guidance — that it was a direct quote from the CSS skill! Though it's missing the guidance about the CSS units that produce better estimates, which is great!

@rviscomi
Copy link
Copy Markdown
Member

Does it seem like a good idea to defer this guide until after I/O?

Yeah let's pause this for now and pick it back up after I/O. I'll move it to draft.

@rviscomi rviscomi marked this pull request as draft May 16, 2026 01:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create guide and evals for the optimize-scroll-stability use case

4 participants