Open flackr opened 3 months ago
To me, this seems to fit more to HTML. Scroll buttons cause an action (scroll up or down) on an element, which is similar to the popovertarget
attribute in relation to elements with the popover
attribute.
So we might introduce an attribute like scrolltarget
that indicates which element to scroll and another one that determines the direction and maybe the amount like scrollby
(with values like e.g. pageup
, pagedown
, lineup
, and linedown
) that determines where the element is scrolled to.
Doing so requires more markup, though also gives users more control over it. E.g. they could provide multiple scroll buttons. This also allows for better accessibility by applying appropiate ARIA information. And there wouldn't be any styling constraints.
Sebastian
So we might introduce an attribute like scrolltarget that indicates which element to scroll and another one that determines the direction and maybe the amount like scrollby (with values like e.g. pageup, pagedown, lineup, and linedown) that determines where the element is scrolled to.
I like this idea, but I really think it's not mutually exclusive with the OP. IMHO if authors get these buttons created by the UA out of the box and they're stylable, then this covers 80% of use-cases without the need for creating extra markup, and that's a big win. Additionally, being able to specify these manually using custom markup would make this feature highly extensible. So I think both solutions should be considered.
Just as a syntax nit, I think this would be better as a functional pseudo ::scroll-button(...)
. That way you can use ::scroll-button(*)
to apply generic styles to your scroll buttons without repetition (in styles or in selectors), and then ::scroll-button(up)
/etc for the specific styles (like content
to actually trigger the creation of the ones you want).
The CSS Working Group just discussed [css-overflow-5] Scroll button pseudo-elements
.
I thought of a similar syntax improvement to that proposed by tab a while back.
But there are some subtle differences:
::scroll-button()
It can select all scroll buttons without *
.up/down
, change it to: ::scroll-button(prev)
and ::scroll-button(next)
Sure, whether we spell the "select all" case as nothing or *
doesn't matter. I think we have a bit more precedent on *
for this sort of thing, but I could be wrong.
For the keywords, note that you can scroll in multiple directions; there will be more than two keywords. I expect the set to be up/down/left/right/block-start/block-end/inline-start/inline-end, and having prev
and next
additionally with the behavior of "whichever axis is scrollable, or block if they both are" sounds nice. (Or maybe "whichever axis has more scrollable length, so a horizontal scroller can have a little bit of vertical overflow without changing the button axis unexpectedly.)
Sure, whether we spell the "select all" case as nothing or doesn't matter. I think we have a bit more precedent on for this sort of thing, but I could be wrong.
My main concern was that *
would lead authors to believe that this function supports CSS selectors.
In addition, can we support scrolling to the scrollbar start and end position here? That is, the first and the last page of the carousel.
Just an update, to list proposed answers to the questions in the OP as something to try to resolve on, I propose the following:
::scroll-button(<direction>)
where direction is up | down | left | right | block-start | block-end | inline-start | inline-end | prev | next
. prev | next
map to the start / end in the axis having more scrollable length, with a preference to the block axis in the case of ties.scroll-marker-group: before
in focus order. They are ordered by block-start, inline-start, block-end, inline-end in order.<direction>
definition, see points 1 and 2.scroll-padding
.4. They scroll by one "page" of scroll distance (e.g. similar to page up / down keys on the keyboard), which in most UA's is 85% of the scrollport size in the relevant axis but are adjusted by
scroll-padding
.
Could it be configurable whether it scrolls one "page" or one snap point/area? I think there are use-cases for both.
Also, when scrolling a fixed amount like 85% with scroll-snapping, an element that was partly obscured before scrolling can end up being partly scrolled out on the other side without ever being fully visible. This is especially frustrating when scrolling in the inline direction, as text can be cropped across lines, making it unreadable. In these cases, we've added code to ensure that only fully visible elements is scrolled out. Would it be possible to address this issue somehow?
@drewstewartdesigns We talked about focus order and tabbing through carousel content just the other day (question 2 in the original issue). What do you think about Rob's proposal above? Is this how you would expect this to work?
- They scroll by one "page" of scroll distance (e.g. similar to page up / down keys on the keyboard), which in most UA's is 85% of the scrollport size in the relevant axis but are adjusted by
scroll-padding
.Could it be configurable whether it scrolls one "page" or one snap point/area? I think there are use-cases for both.
Also, when scrolling a fixed amount like 85% with scroll-snapping, an element that was partly obscured before scrolling can end up being partly scrolled out on the other side without ever being fully visible. This is especially frustrating when scrolling in the inline direction, as text can be cropped across lines, making it unreadable. In these cases, we've added code to ensure that only fully visible elements is scrolled out. Would it be possible to address this issue somehow?
Do you have an example? The way that we avoid this issue for carousel experiences is by ensuring that we have appropriate snap areas. I.e. we will target scrolling 85% but given scroll-snap-type: x mandatory
it will force it to align to the nearest snap area. I think that defining snap areas would be the recommended way to avoid the scroll resting between lines.
Do you have an example? The way that we avoid this issue for carousel experiences is by ensuring that we have appropriate snap areas. I.e. we will target scrolling 85% but given
scroll-snap-type: x mandatory
it will force it to align to the nearest snap area. I think that defining snap areas would be the recommended way to avoid the scroll resting between lines.
I made a quick example here: https://codepen.io/johannesodland/pen/WNqmoYy
Before scrolling: the 3rd item is partially visible on the right side.
After scrolling 85%: it snaps to item 4, leaving item 3 partially visible on the left side.
I made a quick example here: https://codepen.io/johannesodland/pen/WNqmoYy
Thanks @johannesodland! I think this is a more general problem with scroll-snap. I filed #10914 to work out how we can make this work as expected (i.e. not skipping over content).
Thanks @johannesodland! I think this is a more general problem with scroll-snap. I filed #10914 to work out how we can make this work as expected (i.e. not skipping over content).
You're right @flackr. Fixing this in scroll-snap seems right. Thanks for filing 🙏
It would still be good to be able to scroll snap-area by snap-area, and not page by page though. There are many use-cases for going item by item, i.e. when the snapped item is styled in a special way either through ::snapped or scroll-driven animations.
The CSS Working Group just discussed [css-overflow-5] Scroll button pseudo-elements
.
The CSS Working Group just discussed [css-overflow-5] Scroll button pseudo-elements
, and agreed to the following:
RESOLVED: add ::scroll-button() pseudo-elements to Overflow 5, as describe din the issue
As part of #9745 I propose adding a pseudo-element which can be created on a scrolling container to provide a button which navigates that scroller. This is a common pattern, typically requiring that developers manually create elements with script to drive these interactions.
Explainer: https://github.com/flackr/carousel/tree/main/scroll-button
E.g. from https://flackr.github.io/carousel/examples/scroll-button/
For a more practical example, see the implicit creation of markers in the carousel demo.
Having these pseudo-elements allows developers to further reduce the amount of extra markup elements they need to add specifically for controls and make their page contents more about the semantics, e.g. a list of content. They can also easily trigger the buttons' presence depending on a state or media query.
Some questions for consideration / resolution: