Skip to content
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

[css-anchor-position] Better handling of scroll position for fixpos elements on first layout #10999

Open
tabatkins opened this issue Oct 3, 2024 · 0 comments

Comments

@tabatkins
Copy link
Member

tabatkins commented Oct 3, 2024

Anchor Positioning has to make some compromises for scrolling-related behavior, because scrolling is done on the compositor (which has limited abilities, basically just shifting pixels around). Basically, you can shift an anchorpos element according to the current scroll position (as that can be done on the compositor), or you can select a fallback according to the current scroll position (this is done back on the main thread and might lag the scroll, but a fallback is generally a large enough visual change that you don't notice the lag).

This, tho, means you can't size an element according to the current scroll position, ever. The spec currently makes all of its scroll-dependent layout decisions based on the initial scroll position only (except for choosing a fallback, which does respond to the current scroll position). This means you can't, for example, open up a customized <select>, and have the height of the dropdown respond to the current area between the anchor and the bottom of the page. If the element is below-the-fold at the initial scroll position, for example, then position-area: bottom is zero-height, even if the current scroll has the element in the middle of the screen with plenty of space below it!

This is a pretty limiting (and somewhat confusing to authors) restriction, even if it's well-intentioned and necessary in general. However, I think we can improve the behavior in a way that will solve these sorts of use-cases naturally, and reasonably understandably for authors.

Proposal

On first layout of an element whose abspos containing block is a scroller (that is, fixpos elements, or abspos elements with a scrolling CB), we calculate the position-area IMCB based on the current position of the anchor and the scrollport (rather than the initial scroll position), and stick with that going forward. This IMCB is also recalculated whenever we change to a different position-fallbacks entry. (Or when it loses its box and regains it, getting a new "first layout". Aka, very similar, possibly the same, as when an element records or forgets its "last remembered size".)

The size of the IMCB is adjusted by scrolling for the purpose of determining when to do fallback, as normal. This just changes what our base value is, by calculating a value at the moment the positioned element is first rendered.

Example

Check out this example, made by @mfreed7. The demo immediately scrolls slightly down and right on load. If you click the button, it renders a popup that's a little too small; in fact its width and height are precisely the correct size for the "bottom span-right" area at initial scroll position (which you can see if you open it, then scroll back up and left). That information is just useless right now, because we're not at the initial scroll position, so it looks awkward and bad. The further down the button is initially, the worse the behavior is.

My proposal would change this behavior, so that when the popup is opened, it observes the actual space between its anchor and the viewport, and gets a reasonable "bottom span-right" area from that. If you then scroll, it will remain the same size, not responding to the new scroll offset (but if you scroll up or left, reducing the available space, it might trigger fallback). If you later close and reopen the popup, it'll freshly observe the actual space again, and size appropriately for that moment, which might be different than what it was the previous time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant