Carousel
A scroll-snap carousel where the browser draws the arrows and the
dots itself. No <button> markup, no JavaScript.
It uses ::scroll-button(), ::scroll-marker
and scroll-marker-group, all covered in the
MDN CSS carousels guide. They are very new and ship in Chromium only for now.
Default
A plain <ul class="carousel"> of
<li> slides. The arrows and the dots below are not
in the markup, the browser generates them. They disable themselves at
the ends via :disabled, and
:target-current tracks the active dot.
Each <li> needs a data-accname
attribute. An empty ::scroll-marker content string leaves
the dot with a blank accessible name, so the label comes from that
attribute instead and text-indent pushes it out of
sight.
-
Slide 1
-
Slide 2
-
Slide 3
-
Slide 4
-
Slide 5
<ul class="carousel">
<li>Slide 1</li>
<li>Slide 2</li>
<li>Slide 3</li>
</ul>
Images
Put an <img> directly inside each
<li> and it's sized to fill the slide
automatically.
<ul class="carousel">
<li data-accname="Slide 1"><img src="/slide-1.jpg" alt="" /></li>
<li data-accname="Slide 2"><img src="/slide-2.jpg" alt="" /></li>
<li data-accname="Slide 3"><img src="/slide-3.jpg" alt="" /></li>
</ul>
Multiple visible slides
Set --visible inline to show more than one slide at a
time. A row of cards that still snaps a full page per swipe.
-
Slide 1
-
Slide 2
-
Slide 3
-
Slide 4
-
Slide 5
<ul class="carousel" style="--visible: 3">
<li>Slide 1</li>
<li>Slide 2</li>
<li>Slide 3</li>
<li>Slide 4</li>
<li>Slide 5</li>
</ul>
Multiple carousels
CSS anchor positioning places the buttons and dots. Each carousel scopes its own anchor, so putting several on one page needs no extra markup.
-
A 1
-
A 2
-
A 3
-
A 4
-
A 5
-
B 1
-
B 2
-
B 3
-
B 4
-
B 5
<ul class="carousel">
<li data-accname="A1">A1</li>
<li data-accname="A2">A2</li>
</ul>
<ul class="carousel">
<li data-accname="B1">B1</li>
<li data-accname="B2">B2</li>
</ul>