You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: css-overflow-5/carousel-explainer.md
+203-1Lines changed: 203 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -261,7 +261,9 @@ ul::column::scroll-marker {
261
261
}
262
262
```
263
263
264
-
## Putting it all together
264
+
## Use cases
265
+
266
+
### Carousels
265
267
266
268
With the features described, developers can create an automatically paginated carousel UX from a semantic list of items, e.g.
267
269
@@ -342,11 +344,100 @@ and only having the user tab through content on the current page.
342
344
}
343
345
```
344
346
347
+
Of note, is that they can mix and match the features they want
348
+
and style each piece.
349
+
350
+
### Table of contents auto-highlighting
351
+
352
+
The scroll marker feature provides a great drop-in way for a table of contents to automatically highlight the current section, e.g.
353
+
354
+
```
355
+
<style>
356
+
/* A floating table of contents similar to spec pages */
357
+
#table-of-contents {
358
+
position: fixed;
359
+
top: 0;
360
+
left: 0;
361
+
scroll-marker-contain: auto;
362
+
363
+
& a:target-current {
364
+
font-weight: bold;
365
+
}
366
+
}
367
+
</style>
368
+
<ul id=table-of-contents>
369
+
<li><a href="#s1">Section 1</a></li>
370
+
<li><a href="#s2">Section 2</a>
371
+
<ul>
372
+
<li><a href="#s2-1">Subsection 1</a>
373
+
<li><a href="#s2-2">Subsection 2</a>
374
+
<li>
375
+
</li>
376
+
...
377
+
<li><a href="#s2">Section n</a></li>
378
+
</ul>
379
+
```
380
+
381
+
### Paginated reading UI
382
+
383
+
A book reading interface can be created by using the automatic pagination. E.g.
384
+
385
+
```html
386
+
<style>
387
+
.book {
388
+
columns: 1;
389
+
overflow: auto;
390
+
scroll-snap-type: xmandatory;
391
+
}
392
+
.book::column {
393
+
scroll-snap-align: center;
394
+
}
395
+
/* Optionally adding next/prev page buttons: */
396
+
.book::scroll-button(next) {
397
+
content: ">" / "Next page";
398
+
}
399
+
.book::scroll-button(prev) {
400
+
content: "<" / "Previous page";
401
+
}
402
+
```
403
+
345
404
## Future work
346
405
347
406
There are a few carousel designs not currently addressed.
348
407
This section enumerates and explores these areas.
349
408
409
+
### Vertical auto-paged carousels
410
+
411
+
Column fragmentation is a convenient way to automatically paginate a list of items horizontally,
412
+
however we should have a mechanism for paginating vertically as well.
413
+
Most likely, this will be of the form `column-wrap: wrap` similar to the `flex-wrap` property,
414
+
resulting in columns wrapping in the block direction after they overflow the inline direction.
415
+
With this a vertically paginated carousel could be defined as the following:
416
+
417
+
```css
418
+
.carousel {
419
+
overflow: auto;
420
+
scroll-snap-type: ymandatory;
421
+
columns: 1;
422
+
column-wrap: wrap;
423
+
}
424
+
425
+
.carousel::column {
426
+
scroll-snap-align: center;
427
+
}
428
+
429
+
.carousel::column::scroll-marker {
430
+
/* marker styles */
431
+
}
432
+
```
433
+
434
+
### Improved pagination styling
435
+
436
+
Many paginated interfaces allow the user to peek into the subsequent / previous pages.
437
+
Column layouts force an integer number of columns per page meaning they always perfectly fill the space.
438
+
This could be supported by allowing for a fractional column value,
439
+
or specifying the desired overlap region.
440
+
350
441
### Cyclic carousels
351
442
352
443
Many carousels allow scrolling from the last item in the list to the first, or vice versa.
@@ -363,3 +454,114 @@ Auto-advancing carousels introduces many potential accessibility issues if not i
363
454
The [Web Accessibility Initiative Carousel Animations](https://www.w3.org/WAI/tutorials/carousels/animations/) guidelines explores the necessary affordances.
364
455
Most carousel experiences can be authored without automatically advancing sections,
365
456
and in the mean-time author script could implement the animation following the WAI guidelines.
457
+
458
+
## Alternative approaches considered
459
+
460
+
There are many other ways that we could deliver these capabilities.
461
+
462
+
### <carousel> element
463
+
464
+
An element could encapsulate a lot of the features without needing to express them directly as CSS properties.
465
+
One of the main challenges with this approach is that carousels have a large amount of variation in their designs.
466
+
This would likely add significant complexity to the design of a high level element,
467
+
or require some of the individual features proposed anyways.
468
+
469
+
### Templated content instead of columns and pseudo-elements
470
+
471
+
It would be nice for authors to be able to slot in rich content,
472
+
as they would with a custom element.
473
+
For example, they could provide atemplate of content to be created per page
474
+
with aslot for the contents of that page.
475
+
476
+
One challenge is that the original content should retain its original structure.
477
+
This may be possible by dynamically slotting elements to particular pages in ashadow tree.
478
+
479
+
### Using regions or grid-flow instead of ::scroll-marker-group
480
+
481
+
It would be reasonable to think that if we had a way of flowing elements into another area,
482
+
we could use that to create the group of scroll markers.
483
+
E.g. you could imagine using the [flow-into](https://drafts.csswg.org/css-regions/#the-flow-into-property) and [flow-from](https://drafts.csswg.org/css-regions/#flow-from) properties as follows:
484
+
485
+
```html
486
+
<style>
487
+
.markers {
488
+
flow-from: markers;
489
+
}
490
+
/* Generated within the element, similar to a ::before pseudo-element. */
491
+
li::scroll-marker {
492
+
flow-into: markers;
493
+
content: '';
494
+
}
495
+
</style>
496
+
<ulclass=scroller>
497
+
<li>Item 1</li>
498
+
<li>Item 2</li>
499
+
<li>Item 3</li>
500
+
</ul>
501
+
<divclass=markers>
502
+
</div>
503
+
```
504
+
505
+
This is in fact very similar to the original direction of this proposal,
506
+
and is nice in its generality, but was abandoned for a few main reasons:
507
+
508
+
1. In most use cases that developers use scroll markers,
509
+
they would want them to flow elsewhere rather than inline where the user is already scrolled to the content.
510
+
Having this implicit with the `::scroll-marker-group` reduces the number of features needed to be combined to establish this.
511
+
A notable exception to this is that when not reflowed they could serve as self links [#10498](https://github.com/w3c/csswg-drafts/issues/10498).
512
+
2. Having an implicit group containing the markers makes allows for the implicit establishment of focusgroup semantics for those markers.
513
+
One is active at a time, and can automatically assign appropriate itemized AX roles.
514
+
If they're completely independent then there's an expectation they're focused in dom order w.r.t. their owning element,
515
+
and not necessarily linked with the other markers.
516
+
3. Requires the developer to create the area for the markers.
517
+
This could be alleviated by allowing the `::before` or `::after` pseudo-elements to contain flowing content,
518
+
but would likely introduce significant complexity. E.g.
519
+
```css
520
+
.scroller::after {
521
+
flow-from: markers;
522
+
}
523
+
```
524
+
525
+
This is still a nice direction to be considered, and potentially which we could even explain the behavior of `::scroll-marker-group` in the future.
526
+
E.g. If we decide to do this later, we could explain that the default `::scroll-marker` `flow-into` value is the `flow-from` established by the `::scroll-marker-group`.
527
+
528
+
### Invoker action and focusgroup invoke action instead of scroll markers
529
+
530
+
We could add a new built-in `invoke-action` (see [invokers](https://open-ui.org/components/invokers.explainer/)) `scrollTo`. When invoked, the `invokeTarget` will be scrolled to within its ancestor scrolling container. E.g.
531
+
532
+
```html
533
+
<button invoketarget="my-section" invokeaction="scrollTo">Scroll to section</button>
534
+
...
535
+
<section id="my-section">
536
+
This will be scrolled into view when you click the button
537
+
</section>
538
+
```
539
+
540
+
Invoker actions are only [invoked](https://open-ui.org/components/invokers.explainer/#terms) on explicit activation,
541
+
and interest actions are shown [interest](https://open-ui.org/components/interest-invokers.explainer/#terms) on focus or hover.
542
+
For scroll markers, we want the action to be taken only when the selected marker changes, which occurs on focus navigation within the group, but not on hover.
543
+
544
+
As such, we'd propose adding the `invoke` keyword to the `focusgroup` attribute to allow invoking the `invokeaction` on focusgroup focus changes. E.g.
Note that this example uses tabindex="-1" to apply the [roving tab index with a guaranteed tab stop](https://open-ui.org/components/focusgroup.explainer/#guaranteed-tab-stop) behavior from focusgroup.
566
+
567
+
This approach implements the navigation behavior, but notably does not explain how scroll markers would track the scroll state and allow styling the active marker.
0 commit comments