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-pseudo-4] Enabling carousel design patterns in CSS #9745

Open
flackr opened this issue Dec 21, 2023 · 5 comments
Open

[css-pseudo-4] Enabling carousel design patterns in CSS #9745

flackr opened this issue Dec 21, 2023 · 5 comments
Labels
css-pseudo-4 Current Work

Comments

@flackr
Copy link
Contributor

flackr commented Dec 21, 2023

Carousels are an often used design pattern on the web. They are used in a variety of contexts, from product listing pages to slideshow like content. OpenUI has explored a range of carousel designs, showing that the specific layout and appearance can vary dramatically. They are also provided by many frameworks as components, however implementing a carousel correctly is complicated and often results in inconsistent and sometimes inaccessible implementations.

There are a variety of problems being solved by carousels, which we believe could be provided by a set of CSS features. Developers could then combine these CSS features to create the various designs. CSS-only component libraries could be built to further simplify this process.

I'd like to share a strawman set of feature proposals that enable the creation of a variety of carousel patterns out of plain HTML lists using CSS. I've put up an explainer with polyfills and demos (e.g. see the full carousel) where you can see the individual features and how they can be combined to make a full fledged CSS carousel. I'd like to introduce the problem, features and get feedback on the overall direction and where to take the discussion.

Explainer: https://github.com/flackr/carousel/

I'm adding this under css-pseudo-4 for now, but likely the features here would span css-grid-2, css-scroll-snap-2, and possibly other specs.

@yisibl
Copy link
Contributor

yisibl commented Jan 8, 2024

Does the existing design consider such a drag switching mode?

drag-tabs.mp4

@flackr
Copy link
Contributor Author

flackr commented Feb 8, 2024

Does the existing design consider such a drag switching mode?

That's a very neat effect! It's possible we could support something like this, but it would likely impose some limitations on the styling of the scroll marker area.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-pseudo-4] Enabling carousel design patterns in CSS, and agreed to the following:

  • RESOLVED: Start overflow-5 draft, editors elika, florian, rob, move the fragmentation appendix from overflow-4 into it, work on addressing paginated overflow and scroll markers
The full IRC log of that discussion <TabAtkins> flackr: i've been xploring how to help devs make better carousels, because they're very common
<TabAtkins> flackr: but people do it in all sorts of ways, and they're often inaccessible or just don't feel like native features
<TabAtkins> flackr: so i've been exploring what we can do to help that
<TabAtkins> flackr: [shows a demo site]
<TabAtkins> flackr: i think there's a small set of new features that would enable implementing the main set of carousel styles
<TabAtkins> flackr: wanna go thru these and discuss them in whole, then break them into independent issues
<TabAtkins> flackr: first is stylable fragmentation
<TabAtkins> flackr: ::fragment, probably border and other layout-inducing properties aren't allowed
<TabAtkins> flackr: important thing is alignment working
<TabAtkins> flackr: you'll notice the dev hasn't decided how many items fit on a page here, the UA has, so as you resize it changes
<TabAtkins> flackr: this also works in more complex cases, like arbitrarily flowing content between pages
<TabAtkins> flackr: a common pattern is you want content in your scroller tha you create nav entry points to
<TabAtkins> flackr: in here the HTML is a list of sections, and we have a new pseudo-element on the section called ::scroll-marker
<TabAtkins> flackr: this automatically flows into a size-contained area adjacent to the scroller
<TabAtkins> flackr: the "scroll markers area", i've put in a specific grid area to the side
<bkardell_> q+
<astearns> zakim, open queue
<Zakim> ok, astearns, the speaker queue is open
<TabAtkins> flackr: and given each a counter so it numbers the sections
<bkardell_> q+
<TabAtkins> flackr: this is probably the most advanced of the features, it requires the markers to be focused, and requires tab-panel navigation features so you can arrow between them
<TabAtkins> flackr: another feature is grid-flow, which is useful when you have content where you want to flow multiple elements into a single grid area, consecutively
<TabAtkins> flackr: this demo is a tabbed display. the tabs get flowed into a single grid area
<TabAtkins> flackr: Tab has a longer description, the short version is you can only flow into your grid parent, so it doesn't change the hierarchy of the DOM
<TabAtkins> flackr: and in this exapmle i had anchor links to cause them to scroll to the associated section
<TabAtkins> flackr: last, in many times you want to create affordances to cause scrolling, like buttons to scroll up or down
<TabAtkins> flackr: proposing we allow this via a pseudo so you don't have to change the semantics of your content
<TabAtkins> flackr: here yoru content is just a scroller, and there are pseudo-element buttons that cause scrolling up and down, and turn off autoamtically when you can't scroll
<TabAtkins> flackr: put all these together, and you see you get a nice little carousel
<TabAtkins> flackr: the nice thing is the actual semantic content is just a list of items
<florian> q+
<TabAtkins> flackr: styles are what makes it a rich scrolling carousel, which we should be able to make accessible to match your current input modality
<TabAtkins> flackr: I have one more example showing scroll markers showing thumbnails
<TabAtkins> flackr: Here using a variable for your image, and since the ::scroll-marker inherits from the element it's annotating, it can pick up that variable
<TabAtkins> flackr: In a future version where you can do attr() as url, we can pull the href directly
<TabAtkins> flackr: so that's a very quick walkthru about how we could turn a simple list of content into a usable carousel
<TabAtkins> flackr: i want to figure out what the best next steps are
<emilio> q+
<TabAtkins> flackr: figure out where to do the individual features, and do proposals?
<TabAtkins> flackr: is anything missing? hopefully my github explainer is sufficient
<TabAtkins> bkardell_: lots of positive things
<astearns> explainer: https://github.com/flackr/carousel/
<TabAtkins> bkardell_: this gets close to a bunch of things iv'e been interested in for a while
<TabAtkins> bkardell_: i have some issues to ask about, like identifying somethin in the DOM with a scroll marker, or some qs about grid-flow
<TabAtkins> bkardell_: but i woudln't expect everything to be crystal clear at this stage
<TabAtkins> bkardell_: I just like it
<florian> q?
<bramus> +1 to that
<TabAtkins> florian: i like it, one quick note on fragment pseudo
<TabAtkins> florian: we had an attempt at this, it was broader because it was also doing layout-affecting properties
<TabAtkins> florian: one note tho was the design wasn't fragment, it's ::nth-fragment() so you could style them differently
<TabAtkins> fantasai: I think it's a litle different
<TabAtkins> iank_: big thing we care about is getting scroll-snap-align to snap to columns rather than elements
<TabAtkins> fantasai: there's a ::column pseudo designed to help with that
<TabAtkins> flackr: there's a few things I want to improve about columns, and maybe make this vertical as well so it's kinda paged
<fantasai> Ah we never specced it, but see https://github.com//issues/6017
<TabAtkins> florian: my point wasn't about how to craete the fragments, the pseudo that lets you target them, if this ::fragment is differnt from the older ::nth-fragment, I'm not sure what the difference would be
<rachelandrew> https://www.w3.org/TR/css-overflow-4/#fragment-styling is the nth-fragment spec
<TabAtkins> florian: but we don't need to reoslve that now, this is good ideas, we might need to reconcile things
<TabAtkins> iank_: ::nth-fragment is strictly more complex
<TabAtkins> fantasai: i think you're not fragmenting the element, you're fragmenting the content into pages
<TabAtkins> fantasai: those fragments are anonymous
<TabAtkins> fantasai: in ::nth-fragment you take an element, tell it to fragment, and now you have three block boxes
<TabAtkins> emilio: how is that different?
<TabAtkins> iank_: the multicol is anonymous here
<TabAtkins> emilio: we have pseudo-elements targetting anonymous boxes of the element
<TabAtkins> iank_: right that's the ::column pseudo that fantasai is talking about
<nicole__> q+
<TabAtkins> florian: so my comment doesn't need resolution, and might be wrong since elika sounds right. we might need to coalesce in the future, but +1 for now
<TabAtkins> emilio: there's also a section in the explainer about inert, do we need to go thru that
<iank_> I suspect the `::column` pseudo would suffice here.
<TabAtkins> flackr: it's still an important feature - most single-item-at-a-time carousels want offscreen content to be inert
<TabAtkins> flackr: right now that's only thru script tho
<TabAtkins> flackr: if we want authors to be able to do this without needing script, we'll need css-controlled inertness
<TabAtkins> flackr: I have a very loose proposal on this
<TabAtkins> flackr: I think this could be useful for some popover cases too
<TabAtkins> emilio: the weird thing about inert is some things need to escape inertness
<TabAtkins> emilio: allowing CSS to change the semantics of that...
<TabAtkins> emilio: in a fullscreen context, letting the non-fullscreen not be inert if CSS overrides seems weird
<TabAtkins> emilio: another question, about scroll-markers
<TabAtkins> emilio: I'm not clear on how that works
<TabAtkins> emilio: the scrolling box generates the markers
<TabAtkins> flackr: no the marker is on the child elements, and they're auto-flowed into a special zone on the nearest scroller
<TabAtkins> iank_: in practice there will be a step after layout which will go explicitly insert these things into a size-contained area
<TabAtkins> emilio: so if you do *::scroll-marker, then everything generates markers that stash on the root scroller?
<TabAtkins> emilio: you'd need to add pseudo-element resolution once per element...
<TabAtkins> emilio: the overhead when you're not using it seems not ideal
<TabAtkins> emilio: just concerned about adding more ::before/after/marker
<TabAtkins> emilio: more unconditional pseudos can add overhead to pages that don't use the feature
<TabAtkins> flackr: I think we could completely skip them if there's not a scrollmarkers area
<TabAtkins> flackr: In my example there's a separate pseudo-element on the container that says it accepts the markers
<TabAtkins> emilio: right, but you'd do this.... i guess you could do all these after layout somehow, i guess that's what Ian is suggesting
<TabAtkins> emilio: it does mean you need to resolve the scroll-markers pseudo on all scrollers
<TabAtkins> emilio: and what triggers the :scroll-markers pseudo?
<TabAtkins> emilio: I don't see a 'content' property
<TabAtkins> flackr: that's a good question, i'd have to clarify
<TabAtkins> TabAtkins: I expect either a 'content' value, or a new property opting the scroller into it
<TabAtkins> emilio: yeah i think a property would make sense, so you don't need a second pass to find out what elements are supposed to generate a pseudo
<TabAtkins> emilio: i guess the ::scroll-marker pseudo is created for any element in the flat tree for which that scroller is its nearest scroll container?
<TabAtkins> flackr: yeah
<TabAtkins> emilio: ok, i think it's a bit complicated but it could be made to work if you don't force an extra style reoslution
<TabAtkins> emilio: if we could control this in a simpler way
<fantasai> TabAtkins: If both of these were generated only when a new property were set, would that solve the concern?
<TabAtkins> emilio: it would help yes
<TabAtkins> emilio: if people set it on the root tho you could still get a lot
<TabAtkins> TabAtkins: yeah but don't do bad things
<TabAtkins> emilio: people do tho ^_^
<TabAtkins> emilio: also a question about how this interacts with root scroller. maybe we just say it doesn't work?
<TabAtkins> flackr: yeah that might make sense. i could imagine it working, but we can see
<TabAtkins> nicole__: yeah like a slide deck. but this isn't trying to solve that, it's a more narrow use-cases
<TabAtkins> emilio: for elements not otherwise scrollable by the user, would that still work
<TabAtkins> emilio: the automatic scrolling buttons, like on an overflow:hidden
<TabAtkins> TabAtkins: you can link to things in a hidden overflow, or use scrollTo()
<TabAtkins> flackr: there are def carousels where devs make it so you can only scroll with the buttons, not otherwise. whether that's good or not is a decision we can make, maybe we don't generate the buttons unless there's a scrollbar
<TabAtkins> emilio: and similarly, more pseudo-element checks to see if any scroller needs to generate these scroller button pseudos
<TabAtkins> emilio: scrollbars already generate some overhead
<TabAtkins> emilio: but maybe similar solution to previous
<TabAtkins> emilio: otherwise tho seems workable, was a bit surprised to see multicol here
<TabAtkins> q+
<TabAtkins> emilio: feels a bit funky for something that isn't columns
<fantasai> TabAtkins: can't do carousels with multicol rn
<TabAtkins> nicole__: i think there's a bunch of stuff here that's hard for devs to do on their own
<TabAtkins> nicole__: when you think about a carousel it seems straightforward, but then responsive, and columns that can hide and show, and items can change their size...
<TabAtkins> nicole__: quite difficult calculations actually
<TabAtkins> nicole__: so anything we can do to support that would be interesting to consider
<TabAtkins> nicole__: last bit, expanding on what emilio said
<TabAtkins> nicole__: lots of use-cases for carousel in commerce. product details pages often have 6-8 carousels: previously looked at, paired products, images, etc
<TabAtkins> nicole__: it's probably good for the web to make commerce pages easier and better
<TabAtkins> fantasai: great exploation, couple of concerns
<TabAtkins> fantasai: for scroll markers, you're focusing on auto-generated stuff
<TabAtkins> fantasai: i think the first step, rather than auto-genning, shoudl be - what if the author builds a lot of elements, how can we make them act like scroll markers
<TabAtkins> fantasai: so my first step, rather than make a bunch of magic pseudos, is okay, we have a scroller, it has content,
<TabAtkins> fantasai: (like ToC in specs, wouldn't it be great to highlight the section you're in)
<TabAtkins> fantasai: so explore what we need to make that work
<TabAtkins> fantasai: and on pagination, before we dive too deeply into pagination buttons, how do we create a widget that has the correct behavior and can trigger it via js
<nicole__> q+
<TabAtkins> fantasai: if i made a button, how do i make it do the scrolls in straightforward way
<TabAtkins> fantasai: so my first suggestion is can we built up the affordances so someone can create the UI in the DOM, and then hook into this behavior in an easy way
<TabAtkins> fantasai: and then from there, can look into pseudo-elements because you don't always want content in the dom since it's presentational
<TabAtkins> fantasai: in terms of prior art, there was a previous proposal for overflow:paged which was implemented in opera
<TabAtkins> fantasai: never really made it because it didn't solve the problem of controls
<TabAtkins> fantasai: authors want to create controls in all kinds of ways, sometimes in the scroller, or outside
<TabAtkins> fantasai: miht not want the controls to be so tightly adjacent in the tree structure
<TabAtkins> fantasai: so autogen is nice, but we need to let authors do what they want
<TabAtkins> fantasai: and then when we generate pseudos, we'll have a good idea of what limitations to palce on them
<florian> q?
<TabAtkins> fantasai: wrt multicol vs dedicated overflow, latter would let you control whethe ryou want a dedicated pgup/pgdn
<TabAtkins> fantasai: but people do other transitions
<TabAtkins> fantasai: if you're flipping between cards in your carousel, is scrolling what you want? or do we need other ways to style the transition. are scroll animations enough?
<TabAtkins> fantasai: those are my thoughts. in terms of what to work on, i think (1) how do we want to create a pagination mode that has easy API for manipulating it
<TabAtkins> fantasai: and allows authors to easily build UI that will do the correct thing
<TabAtkins> fantasai: and on scroll marker side, how to have the behavior where it knows it's the active thing and scrolls to the correct position
<TabAtkins> fantasai: can we do that in a way so the interaction between them is more declarative and straightforward than it is now
<TabAtkins> fantasai: maybe a fully declarative binding would make things a lot easier
<TabAtkins> fantasai: and then from there the auto-generating part... it's a little too tied to grid at the moment
<bradk> q+
<TabAtkins> flackr: i don't think any of the stuff is tied to grid except grid-flow. you can create most bits without grid
<Zakim> fantasai, you wanted to comment on in-DOM scroll markers vs decorative
<TabAtkins> flackr: for dedicated elements, one thing that pseudos are hugely advantageous for is establihsing that link with what it does
<TabAtkins> flackr: a scroll button needs a way to refer to what scroller it's touching
<TabAtkins> flackr: which i'm open to, but we need ways to repeat it on the page so you don't need to generate unique identifiers
<dholbert> TabAtkins (IRC): I agree with fantasai (IRC) that whatever functionality we do here shouldn't be magically tied just to the pseudos
<dholbert> TabAtkins (IRC): need to have some way to invoke them from JS. Flackr mentioned getting the button from the scroller; that could be a property, or linked in the DOM
<dholbert> TabAtkins (IRC): having the pseudos being the only way to get the "magical" hookup is probably reasonable. we can play in that space and see if real DOM can also get a magical thing too
<dholbert> TabAtkins (IRC): flackr, you were talking about multicol for pagination in your examples. Is that the only pagination mechanic?
<dholbert> flackr (IRC): there was an idea of tying this to flex-wrap also. But there are many use-cases where the content is reflowing, and columns does everything that you want to there
<dholbert> flackr (IRC): I do call out in the explainer that columns doesn't address everything; e.g. you can't reserve some space to peak into space beyond current area
<dholbert> TabAtkins (IRC): so your big final demo, each section is filling one column, with a column-break after each one?
<dholbert> iank_ (IRC): expanding on the flex thing: you could imagine a flexbox row that wraps. Doesn't stack in the cross axis, but stacks in the main axis
<dholbert> iank_ (IRC): then, you'd need something like scroll-snap-align to target individual flex lines which don't generate fragments today
<dholbert> iank_ (IRC): that's *a* path, potentially
<dholbert> TabAtkins (IRC): in this example with 3 items visible at a time, what causes these 3 columns to be a page?
<dholbert> flackr (IRC): the fact that we've told them to flow them to columns. that creates an anonymous fragmented container
<dholbert> TabAtkins (IRC): I see `columns:1`; I'm confused about where the column fragmenting is happening
<dholbert> flackr (IRC): [brings up a simpler example with One | Two | Three]
<dholbert> florian (IRC): `columns:1` isn't "no columns". It's start with one column, and then autogenerate more
<dholbert> flackr (IRC): if I do `columns:2`, then it's fitting 2 per area and snapping
<dholbert> TabAtkins (IRC): the thing I was missing is that the 3 children are 3 inline-blocks filling a single column horizontally. Not individual columns
<flackr> Example is at https://flackr.github.io/carousel/examples/fragmentation/
<TabAtkins> nicole__: elika, sounded like starting from a version where the dev provides the markup, how would they know the number of markers?
<TabAtkins> fantasai: for some examples, the number of pages is dicated by content, not layout concerns. lots of carousels that are one per page
<TabAtkins> fantasai: we have a similar issue in specs - the ToC scrolls to the part of the spec. we don't have a binding in the other direction. when i scroll to a new section in the spec, or my carousel, i want the correct section/marker to get highlighted
<TabAtkins> fantasai: no connection back to the navigation
<TabAtkins> nicole__: like in teh bootstrap docs?
<TabAtkins> fantasai: yes, it's real common, but it's complicated
<TabAtkins> fantasai: so it would be nice to create this association, as long as you have elements that are in view
<TabAtkins> fantasai: so you could style the markers appropriately, and also make them clickable
<bkardell_> this is why I mentioned the element thing as desirable -- this is I think the same challenge with the tabs looking one I think, currently
<TabAtkins> fantasai: the case where you have something paginating based on how much content fits, then you might want page markers rather than content markers, we'd want to auto-gen those
<TabAtkins> fantasai: but on the way to that i want to make sure elements in the dom can work
<bramus> Note that the scrollspy pattern became easier to do thanks to scroll-driven animations.
<TabAtkins> fantasai: it doesn't require us to figure out nearly as much stuff before we can start helping authors
<TabAtkins> nicole__: I think there's a bit of danger becuase it's hard to say what's a carousel and waht isn't
<TabAtkins> nicole__: boundaries have blurred
<TabAtkins> nicole__: so figuring out which use-cases are in and which are out is good
<TabAtkins> fantasai: maybe, but i don't want to limit us to such a specialized use-case that you can't do more things with it
<TabAtkins> fantasai: building up pseudo-elements that have a very simple relationship to their originating element - kinda a pain in the ass but still relatively simple
<TabAtkins> fantasai: but doing more complicated things where they lay out in a way that's not directly associated with the alyout tree, that's a lot more complicated
<TabAtkins> nicole__: i sort of hate the way this works in form controls, with IDs and such where you need unique ids to hook them all together
<TabAtkins> fantasai: we've been doing bindings with scoped names in various things in CSS
<florian> q?
<TabAtkins> fantasai: but you might also want to pick up DOM relationships that are already there, using IDs or the like
<TabAtkins> fantasai: but i just want to see - you won't need nearly as much JS with a bunch of these abilities
<TabAtkins> fantasai: they can generate a few elements, and then just hook up the properties.
<TabAtkins> fantasai: JS is hard, if it's complex authors can screw up accessibility
<TabAtkins> fantasai: If we can give all the bheavior and they just have to provide markup, we're already way ahead
<TabAtkins> bradk: when i've heard about this, it reminded me of regions, especially the grid-flow
<TabAtkins> bradk: is this sorta a subset of that? or superior to that? have we considered synergy with those earlier ideas with regions?
<TabAtkins> bramus: even continue:fragments is sorta an alternative to using columsn
<fantasai> scribe+
<fantasai> s/bramus/bradk/
<dholbert> TabAtkins (IRC): I can answer about the grid-flow thing
<florian> q+
<dholbert> TabAtkins (IRC): for the grid-flow functionality, we're learning some of the lessons from regions
<dholbert> TabAtkins (IRC): being too open in what sort of movement you allow across DOM causes issues for layout and a11y
<dholbert> TabAtkins (IRC): having things reparented effectively in the DOM tree can be problematic for a11y tools
<dholbert> TabAtkins (IRC): for this reason, `grid-flow` in this proposal is very limited
<dholbert> TabAtkins (IRC): With this proposal, all the children maintain the same parent-child relationship that they had before. This doesn't change those relationships, very intentionally
<dholbert> TabAtkins (IRC): This is trying to avoid the issues that we ran into before
<dholbert> bradk (IRC): so looking at a more limited set of problems here?
<dholbert> TabAtkins (IRC): yup. Plus, since they're grid items, they'll be block formatting contexts, which are easier to lay out into a new container
<dholbert> TabAtkins (IRC): If we were piecing together non-BFC things from different places in the layout tree, there'd be much more complexity
<dholbert> TabAtkins (IRC): this avoids complexity, circularity
<dholbert> iank_ (IRC): the more we dived into use-cases here, the more we realized that stuff could just be solved by pseudo reparenting
<dholbert> florian (IRC): I think the situation with continue:fragment vs. multicol is similar in a way
<TabAtkins> florian: you might be able to do them multicol or continue;fragments, but multicol is so much simpler
<TabAtkins> florian: we already know how to do the multicol stuff
<TabAtkins> florian: and many times multicol is good enough for majority of cases anyway
<TabAtkins> florian: when we get to the point where we *do* need more, we can swap into that
<TabAtkins> bradk: yeah, was wondering if things like continue:fragments was intended to be a part of this
<TabAtkins> florian: I haven't looked deeply into this, but I believe that it should be psosible in the future to swap in a continue-fragments rather than multicol
<TabAtkins> flackr: yes
<TabAtkins> fantasai: rob, questions?
<TabAtkins> flackr: feedback has been great. we outlined a few things it would be nice to work on first, maybe scroll-markers first. what spec would it belong in?
<TabAtkins> fantasai: the pseudo-elements, or the scrolling binding?
<TabAtkins> flackr: both/either
<TabAtkins> fantasai: hmm, unsure. maybe scroll-snap is closest?
<TabAtkins> TabAtkins: yeah scroll snap 2 has some similar ideas
<TabAtkins> TabAtkins: but chrome has an impl trying to stabilize a few of these ideas
<TabAtkins> fantasai: overflow 5?
<TabAtkins> florian: yeah that might work
<TabAtkins> fantasai: it would let us centralize all the overflowing things together
<TabAtkins> fantasai: so i think proposal is to start overflow 5 draft, to explore paginating overflow, and scroll markers, and move appendix stuff into it
<TabAtkins> florian: Rob as a co-editor?
<TabAtkins> fantasai: yes definitely
<TabAtkins> fantasai: editors would be me, florian, rob
<TabAtkins> fantasai: comments? objections?
<TabAtkins> RESOLVED: Start overflow-5 draft, editors elika, florian, rob, move the fragmentation appendix from overflow-4 into it, work on addressing paginated overflow and scroll markers
<TabAtkins> TabAtkins: do we want to resolve about starting on ::grid-flow?
<TabAtkins> fantasai: maybe a separate discussion

flackr added a commit to flackr/csswg-drafts that referenced this issue Jun 10, 2024
Per the resolution in w3c#9745, this starts the css-overflow-5 spec,
initially moving over the fragmentation appendix from css-overflow-4 into it.
flackr added a commit that referenced this issue Jun 10, 2024
Per the resolution in #9745, this starts the css-overflow-5 spec,
initially moving over the fragmentation appendix from css-overflow-4 into it.
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-pseudo-4] Enabling carousel design patterns in CSS.

The full IRC log of that discussion <TabAtkins> flackr: [introduces self]
<TabAtkins> flackr: I've been doing a lot of exploration into new UI patterns on the web, one of which is carousels.
<TabAtkins> flackr: if you look up "should I use a carousel", the common answer is no
<TabAtkins> flackr: session complete
<TabAtkins> flackr: this website goes into a bunch of pitfalls people often run into when they write carousels
<TabAtkins> flackr: This particular example is a bad carousel too, it auto advances, I can't swipe, etc
<TabAtkins> flackr: despite the fact that they're often done poorly, there are many many carousel components
<TabAtkins> [tech issues]
<TabAtkins> flackr: this is bootstrap, for example
<TabAtkins> flackr: OpenUI has done a long exploration of carousel pattern
<TabAtkins> flackr: Adam created a demo showing all the different "shapes" for a carousel
<TabAtkins> flackr: dots, thumbnails, no page markers, no arrows, previews of the next item
<TabAtkins> flackr: you can have shopping carousels, where you move be3tween *pages* of items
<TabAtkins> flackr: whether we like them or not, devs create carousels, so we should make them better
<TabAtkins> flackr: looking at most of these, there's some common features
<TabAtkins> flackr: CSS today comes pretty close to letting you build something like this in a scrolling elmeent
<TabAtkins> flackr: with Scroll Snap you can make something that slides from pane to pane, supports touch
<TabAtkins> flackr: because eit's just a scroll, any scrolling mechanism works, better than explicit event handlers
<TabAtkins> flackr: you just have to roll a few pieces yourself
<TabAtkins> flackr: that's what Adam did on his site, making a few extra bits in JS
<TabAtkins> flackr: so I looked into what we can do better, so it's just scrolling, we can accelerate that, and navigate it in the browser so it's more accessible
<TabAtkins> flackr: I have an explainer where I touch on these features
<TabAtkins> flackr: you have scroll-snap, as mentioned
<TabAtkins> flackr: you often have buttons to scroll between items/pages
<flackr> demo: https://gui-challenges.web.app/carousel/dist/
<TabAtkins> flackr: there's often a progress indicator
<TabAtkins> flackr: the progress updates as you scroll
<TabAtkins> flackr: and if you have all of these things, you can make a carousel
<TabAtkins> flackr: you can change where these things are positioned, you can make vertical carousels, any combo
<TabAtkins> flackr: breaking these down, I think we can make it possible to express in css
<TabAtkins> flackr: i've outline a set of features i'd like to dive into, to explain what part each is offering and how it's used to build a carousel
<TabAtkins> flackr: first, some form of stylable fragmentation
<TabAtkins> flackr: to create automatic pagination
<TabAtkins> flackr: if you use multicol fragmentation, columns:1
<TabAtkins> flackr: you'll get a layout with one page of content per fragment
<TabAtkins> flackr: you'll get a long list of columns, split up into "pages"
<TabAtkins> flackr: if we let yous corll-snap to that, you get a paginated experience
<TabAtkins> flackr: scroll markers if about those progress indicators
<TabAtkins> flackr: skipping the "flow into Grid areas" temporarily
<TabAtkins> flackr: scroll buttons are the next/prev buttons
<TabAtkins> flackr: You can roll them on your own, but it would be convenient to auto create them
<TabAtkins> flackr: finally, inert
<TabAtkins> flackr: the ARIA authoring guidelines for carousels recommend that tonly the onscreen content is present in tab order, and the next/prev buttons are used to bring up the next slide
<TabAtkins> flackr: so you don't trap people in a long list of slide contents
<TabAtkins> flackr: currently authors have to do this manually, updating the inert attribute on each slide
<TabAtkins> flackr: but you could imagine updating this automatically as you scroll or click the buttons
<TabAtkins> flackr: so that's a quick overview, I want to dive into some of them

@tabatkins
Copy link
Member

Another chunk of conversation logs from the end of the session:

```

15:26 <@tabatkins> wendyreid: I noticed in a lot of examples - and i've also struggled with this for devs - I haven't seen a lot where each item in the carousel contains a bunch of other content
15:26 <@tabatkins> wendyreid: Like say each has an image, text, and a call to action button
15:26 <@tabatkins> wendyreid: but you also want item-by-item interaction as well as interaction in each
15:26 present+
15:26 <@tabatkins> wendyreid: so in this example (image with label) what if there's a button inside of each, too
15:27 <bkardell_> q+
15:27 — Zakim sees wendyreid, bkardell_ on the speaker queue
15:27 <@tabatkins> flackr: this is just content inside a scrollable element, we're not treading new ground
15:27 — @dbaron ack wendyreid
15:27 — Zakim sees bkardell_ on the speaker queue
15:27 polyfilled demo: https://flackr.github.io/carousel/examples/carousel/image/
15:27 <@dbaron> s/syns:/cyns:/g
15:28 <@tabatkins> TabAtkins: the only particularly new thing here is the auto-inerting. only the visible stuff in the scroller show up in the tab order, until you scroll pages
15:28 <@tabatkins> wendyreid: in this example I might have expected focus to move to the next button at the end, rather than past
15:28 q+
15:28 — Zakim sees bkardell_, cyns on the speaker queue
15:28 <@tabatkins> flackr: we've seen both. the APG example has the buttons together in tab order, but they're visually together there.
15:28 <Patrick_H_Lauke> Agree with Wendy here ... APG pattern may not be the be all/end all
15:28 <@tabatkins> wendyreid: Yes, it depends on the visual placement
15:29 — bkardell_ where is Patrick_H_Lauke ?
15:29 <@tabatkins> flackr: I haven't mentioned this yet, thinking of having invokercommand to let you make your own buttons that scroll; you can put them anywhere
15:29 <@tabatkins> flackr: maybe for generated content, we could use reading order to change where they are
15:30 <@tabatkins> TabAtkins: except those are abspos usually, so they "wont' participate" in reading order. but we could build on the machinery.
15:30 ack me
15:30 — Zakim sees bkardell_ on the speaker queue
15:30 <@tabatkins> cyns: we were talkinga bout that in aria, having to go thru the entire slide to get to the next button can be annoying
15:30 <@tabatkins> bkardell_: I have now twice tried to tackle tabs
15:31 <@tabatkins> bkardell_: panels and panelsets
15:31 <bkardell_> openui/open-ui#559
15:31 <@tabatkins> bkardell_: most recently in openui
15:31 demo showing scroll-marker based tabs: https://flackr.github.io/carousel/examples/scroll-marker/tabs/
15:31 <@tabatkins> bkardell_: got far, then got feedback that a bunch of the cases, Sarah higgley and I discovered that sometimes things that look like tabs shoudlnt' be ARIA tabs, but what should they be instead?
15:31 <@tabatkins> bkardell_: this might be the answer
15:32 <@tabatkins> bkardell_: these look a lot like tabs, but they're actually panels in a document, a kind of scroll
15:32 <@dbaron> s/Higgley/Higley/
15:32 <@tabatkins> bkardell_: I like that
15:32 <@dbaron> s/higgley/Higley/
15:32 <@tabatkins> bkardell_: especially since with a MQ you could change how it's displayed, maybe on your phone it's just a long scroll of content
15:32 <@tabatkins> bkardell_: it's kinda a design affordances sometimes, different from browser tabs. those aren't design, they're a doc manager
15:33 <@tabatkins> bkardell_: I'd love to hear from more a11y people if you think this might be a decent pattern for attacking this kind of tabs
15:33 q+
15:33 — Zakim sees bkardell_, smfr on the speaker queue
15:33 <@tabatkins> flackr: that's also one of the benefits that semantically it's just a list of content. you can just change the way it's presented based on form factor
15:33 <@tabatkins> ack bkardell_
15:33 — Zakim sees smfr on the speaker queue
15:33 <@tabatkins> cyns: would you change the a11y mapping based on that?
15:33 <@tabatkins> bkardell_: that's the question
15:34 <@tabatkins> bkardell_: maybe we already have things sorta like that, like collapse the menu up
15:34 <@tabatkins> bkardell_: but it seems more known-quality and subtle
15:34 <@tabatkins> cyns: the browser can do it in this case
15:34 <@tabatkins> bkardell_: yeah, and this is like scrollbars. we don't say "this is a scroll area" like in Java, you just get a scroller if you need it
15:35 <@tabatkins> bkardell_: here we can see "if you have the real estate, show them in panels" but if it's small make it just scrollable
15:35 <@tabatkins> cyns: I like how simple the code is, especially compared to other carousels
15:35 <@tabatkins> hdv: so this example wouldn't be ARIA tabs?
15:35 <@tabatkins> bkardell_: I think so, I think just having it be a scroller would be a better solution
15:36 <@tabatkins> bkardell_: ARIA tabs are cases where they're app-style tabs, more like browser tabs. those should be tabs.
15:36 <@tabatkins> bkardell_: but they're also not likely to change, they're not a style choice
15:36 q-
15:36 — Zakim sees no one on the speaker queue
15:36 <@tabatkins> dbaron: I spent an hour talking to Brian and Sarah Higley a year or so ago. I'm rereading my comments, from the long issue Brian linked.
15:37 <@tabatkins> dbaron: One thing - do you want find in page to find things in the other tab? do you want all tabs to show in a printout or all?
15:37 <@tabatkins> dbaron: I think suggestion was if find-in-page shouldn't switch the tab, and user only wants one tab in the printout, it's probably aria tabs. if it's the other way around, probably the panel-set tabs
15:37 <@tabatkins> dbaron: I haven't internalized it enough to be sure I believe it
15:37 <@tabatkins> dbaron: especially that those two things correlate well
15:38 <@tabatkins> bkardell_: i'm not sure I believe it. but enough people I respect have articulated it in a way that makes me think we need to take it seriously
15:38 <@tabatkins> bkardell_: if we find something that lets us make that distinction, we should do it
15:38 <@tabatkins> bkardell_: but yeah, I don't think everybody has the same feelings
15:38 <@tabatkins> bkardell_: not everyone agrees on the breakdown, or even that there should be a breakdown
15:39 <@tabatkins> bkardell_: but I think we've articulated differences that do make sense
15:39 <@tabatkins> hdv: user research about whether they prefer panel-sets vs aria tabs, doesn't seem to be a clear preference
15:39 <@tabatkins> bkardell_: does seem to likely be a user preference, people can prefer either
15:40 <@tabatkins> hdv: we saw people who liked either, makes it hard to choose
15:40 <@tabatkins> wendyreid: also it's not always semantically easy to express "going to different place on this page" vs "going to different page"
15:40 <@tabatkins> wendyreid: sometimes "tab navigation" is doing either
15:40 <@tabatkins> wendyreid: not clear to the user
15:40 <@tabatkins> wendyreid: and not really a semantic way to indicate that
15:41 <@tabatkins> ydaniv: wild idea, if I put overflow:clip (and rest is inert) it would be tabs?
15:41 <Patrick_H_Lauke> overflow:hidde (hdv)
15:42 <@tabatkins> flackr: one idea that came up in ARIA, could have a role on the scrolling element that determines the generated content role
15:42 — bkardell_ is real curious what smfr wanted to say and if Patrick_H_Lauke has thoughts
15:42 <@dbaron> (openui/open-ui#559 (comment) was the summary of the discussion that I mentioned above)
15:42 <@tabatkins> smfr: I had questions about the real ARIA tabs, presented today was high-level functionality
15:43 <Patrick_H_Lauke> bkardell I'm neutral on this. users often...don't care, as long as it works correctly and makes semantic sense
15:43 <@tabatkins> smfr: for scrolling carousels, wonder if we should do it for tabs too
15:43 <Patrick_H_Lauke> q+
15:43 — Zakim sees Patrick_H_Lauke on the speaker queue
15:43 <@tabatkins> smfr: you can do tabs today with radio buttons and :checked
15:43 <@tabatkins> smfr: do we want this to work better in this interface?
15:43 <@tabatkins> smfr: id' probably want non-visible tabs to be display:none for perf reasons, for example
15:43 <@tabatkins> flackr: so something similar to scroll markers, but display:nones the non-active content
15:44 <@tabatkins> there's definitely something good in there
15:44 <@tabatkins> smfr: also, you said the scroll buttons are siblings of the scroller, how does that work for the root scroller?
15:44 <@tabatkins> flackr: they're children in that case, you'd use fixpos to position them
15:45 — @dbaron ack Patrick_H_Lauke
15:45 — Zakim sees no one on the speaker queue
15:45 <@tabatkins> Patrick_H_Lauke: heard about some devs doing this with radio buttons/etc
15:45 <@tabatkins> Patrick_H_Lauke: that's obvs semantically very dubious
15:45 <@tabatkins> Patrick_H_Lauke: much more positive with what i'm seeing here
15:45 <@tabatkins> Patrick_H_Lauke: more bespoke, rather than a perversion of CSS
15:46 <@tabatkins> Patrick_H_Lauke: explaining to a screen reader that, yes, there are radio buttons but they actually switch visual tabs, it's bad
15:46 <@tabatkins> Patrick_H_Lauke: so this is a good step forward
15:46 <@tabatkins> flackr: We're at time, wrapping up
15:46 <Patrick_H_Lauke> (in answer to brian's earlier question, i hid in my hotel room for the session)
15:47 <Patrick_H_Lauke> great stuff, thanks all

</details>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-pseudo-4 Current Work
Projects
Status: Wednesday afternoon
Development

No branches or pull requests

4 participants