w3c / csswg-drafts

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

[css-overflow-5] Tree structure of scroll container controls #11125

Open flackr opened 1 week ago

flackr commented 1 week ago

::scroll-marker-group and ::scroll-button(*) are pseudo elements that originate from the scrolling container. These elements should not move with scrolling content as they are meant for navigating the scroller. Structurally we need to decide if they are children of the originating element scrolling container (like most existing pseudo-elements), or whether they should be siblings.

Options:

  1. They are normal children. Developers need to switch to a different positioning model that makes them not contained by (or shifted by) the scrolling content of the scrolling container. E.g. position: fixed or position: absolute (as long as the scroller isn't position: relative), or anchor positioned. It is impossible to reserve space for them outside of the scroller.
  2. They are siblings before/after the scroller. They can reserve space in the flow of the scroller's container, possibly be positioned into grid areas or participate in ancestor flexbox sizing. Additionally like other siblings their in flow position is outside of the box of the scrolling container.
  3. They are children of the scrolling container but not part of the scrolling content, instead being considered part of the box model for the scrolling container itself (and thus not scrolled by it). We'd have to think more about how exactly this would work and render, but conceptually they would be within the box of the scrolling container.

Demo of the approximate layout of the different approaches with minimal extra position styling: https://flackr.github.io/carousel/examples/pseudo-structure/

I propose that we go with option 2 as it's easy to understand and I think sets up a lot of the right structure by default.

@tabatkins

ydaniv commented 1 week ago

So with option 2 the generated tree would look like this:

::scroll-button(*)
<scroller></scroller>
::scroll-marker-group

correct? But they're still selected as children of scroller, like scroller::scroll-button(*)?

I guess options 2 and 3 allow you to break out of the scroller's clipping, so that gives more styling freedom OOTB.

IIUC, with option 1 they're clipped by the scroller, which gives less styling freedom for this model. Although this option feels more intuitive, I suppose it will require more opinionated default UA styling to be visually correct by default, since without correct initial positioning it would appear broken.

I think it would be helpful to visualize how we want these to render by default? And with what UA styles? And then see for each option, what it takes to reach different layout use-cases.

flackr commented 3 days ago

So with option 2 the generated tree would look like this:

::scroll-button(*)
<scroller></scroller>
::scroll-marker-group

correct? But they're still selected as children of scroller, like scroller::scroll-button(*)?

That's correct. The chromium implementation of ::scroll-marker-group and the spec suggest matches option 2 right now. However currently the chromium implementation of ::scroll-button(*) is implemented following option 1, so you can see the difference between them on the canary channel with experimental web platform features enabled as well.

I guess options 2 and 3 allow you to break out of the scroller's clipping, so that gives more styling freedom OOTB.

IIUC, with option 1 they're clipped by the scroller, which gives less styling freedom for this model. Although this option feels more intuitive, I suppose it will require more opinionated default UA styling to be visually correct by default, since without correct initial positioning it would appear broken.

That's right, it takes more careful styling to get them to behave as expected and is less flexible. Note that they don't necessarily have to be clipped by the scroller, if they're position: absolute; and the scroller is position: relative than things mostly work as expected. However, this is also limiting, and feels like a bit of a gotcha.

I think it would be helpful to visualize how we want these to render by default? And with what UA styles? And then see for each option, what it takes to reach different layout use-cases.

I made a demo page showing roughly what the different structures would look like if minimal styling were used. Were you thinking that it would be helpful to show how a developer might achieve some common expected designs with each structure?