Accessability pass

This commit is contained in:
vollstock committed 2026-10-03 21:24:35 +02:00
1 parent bafae5ee5f
commit 1b79ceb155
4 files changed
+127 -84

No files matched your search

+34 -33
View File
@@ -8,16 +8,16 @@ It does not implement every feature found in other carousel libraries. Instead,
Mouse-drag behavior closely follows native touch scrolling in the browser, including inertia and snapping to a slide. Thus dragging with the mouse feels pretty identical to native scrolling on a touch device or using a trackpad. Mouse-drag behavior closely follows native touch scrolling in the browser, including inertia and snapping to a slide. Thus dragging with the mouse feels pretty identical to native scrolling on a touch device or using a trackpad.
| File | Size | | File | Size | gzip |
| ---------- | ------: | | ---------- | ------: | -----: |
| snappy.js | 6,17 kB | | snappy.js | 7.5k kB | 2.2 KB |
| snappy.css | 1,11 kB | | snappy.css | 0.9 B | 0.4 KB |
## Usage ## Usage
### CSS only for a basic scroll container ### Only CSS for a basic scroll container
You can use Snappy without JavaScript. This gives you a simple CSS-only scroll container with snapping slides. You can use Snappy without JavaScript. This gives you a simple CSS-only scroll container with snapping slides.
@@ -26,13 +26,14 @@ You can use Snappy without JavaScript. This gives you a simple CSS-only scroll c
<link rel="stylesheet" href="dist/snappy.css"> <link rel="stylesheet" href="dist/snappy.css">
<!-- add this structure --> <!-- add this structure -->
<div class="snappy-carousel"> <section class="snappy-carousel" aria-labelledby="carousel-heading">
<div class="scroll-container"> <h1 id="carousel-heading" class="visuallyhidden">Carousel Heading</h1>
<div class="slide">1</div> <ul class="scroll-container">
<div class="slide">2</div> <li class="slide">1</li>
<li class="slide">2</li>
... ...
</div> </ul>
</div> </section>
``` ```
Snappy is mostly unstyled, leaving the appearance up to you. Snappy is mostly unstyled, leaving the appearance up to you.
@@ -51,10 +52,6 @@ Options
data-direction="x" (default) data-direction="x" (default)
data-direction="y" data-direction="y"
data-gap="var(--size-1)"
data-gap="10px"
data-gap="1rem"
data-snap-stop="always" data-snap-stop="always"
data-snap-stop="normal" (default) data-snap-stop="normal" (default)
@@ -62,17 +59,18 @@ data-snap-align="center" (default)
data-snap-align="start" data-snap-align="start"
data-snap-align="end" data-snap-align="end"
--> -->
<div class="snappy-carousel" <section class="snappy-carousel" aria-labelledby="carousel-heading"
data-gap="1rem" data-direction="y"
data-snap-align="start"> data-snap-align="start">
<h1 id="carousel-heading" class="visuallyhidden">Carousel Heading</h1>
<div class="scroll-container"> <ul class="scroll-container">
<div class="slide">1</div> <li class="slide">1</li>
<div class="slide">2</div> <li class="slide">2</li>
... ...
</div> </ul>
</div> </section>
```
### Add JavaScript for a carousel ### Add JavaScript for a carousel
@@ -83,17 +81,20 @@ Including the JavaScript adds the following features:
- Mouse dragging - Mouse dragging
```html ```html
<div class="snappy-carousel" data-gap="1rem" data-snap-align="start"> <section class="snappy-carousel" aria-labelledby="carousel-heading"
<div class="scroll-container"> data-direction="y"
<div class="slide">1</div> data-snap-align="start">
<div class="slide">2</div> <h1 id="carousel-heading" class="visuallyhidden">Carousel Heading</h1>
... <ul class="scroll-container">
</div> <li class="slide">1</li>
<li class="slide">2</li>
...
</ul>
<button class="prev">❮</button> <button class="prev">❮</button>
<button class="next">❯</button> <button class="next">❯</button>
<div class="pagination"></div> <ul class="pagination"></ul>
</div> </section>
<script src="dist/snappy.js" defer></script> <script src="dist/snappy.js" defer></script>
``` ```
+53 -40
View File
@@ -3,8 +3,12 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description"
content="Snappy Carousel Demo – Snappy is a lightweight carousel. Mostly CSS-only, with some Javascript for navigation and drag support." />
<title>Snappy</title> <title>Snappy</title>
<link rel="stylesheet" href="dist/snappy.css">
<style> <style>
html, html,
body { body {
@@ -33,8 +37,10 @@
/* Custom snappy styling */ /* Custom snappy styling */
/* Colors from Open color (https://yeun.github.io/open-color) */ /* Colors from Open color (https://yeun.github.io/open-color) */
.snappy-carousel { .snappy-carousel {
margin-bottom: 2rem;
.scroll-container { .scroll-container {
max-height: 400px; max-height: 420px;
gap: 0.5rem; gap: 0.5rem;
} }
@@ -44,7 +50,6 @@
align-items: center; align-items: center;
width: 75%; width: 75%;
aspect-ratio: 3/2; aspect-ratio: 3/2;
min-height: 200px;
max-height: 400px; max-height: 400px;
border-radius: 1rem; border-radius: 1rem;
border: 1px solid #ced4da; border: 1px solid #ced4da;
@@ -98,15 +103,18 @@
} }
} }
.prev:disabled,
.next:disabled {
opacity: 0.5;
}
.pagination { .pagination {
display: inline-flex; display: inline-flex;
margin-top: 1rem; margin-top: 1rem;
} }
.pagination .dot { .pagination .dot {
width: 0.66rem !important; border-radius: 1lh;
height: 0.66rem !important;
border-radius: 0.33rem;
background-color: #dee2e6 !important; background-color: #dee2e6 !important;
margin: 0 0.25rem; margin: 0 0.25rem;
@@ -127,14 +135,16 @@
} }
} }
</style> </style>
<link rel="stylesheet" href="dist/snappy.css">
</head> </head>
<body> <body>
<header>
<h1>Snappy</h1>
</header>
<h1>Snappy</h1> <main>
<!-- <!--
Options Options
------- -------
@@ -149,40 +159,43 @@
data-snap-align="center" data-snap-align="center"
data-snap-align="start" data-snap-align="start"
data-snap-align="end" data-snap-align="end"
--> -->
<div class="snappy-carousel"> <section class="snappy-carousel" aria-labelledby="horizontal-carousel-heading">
<div class="scroll-container"> <h2 id="horizontal-carousel-heading" class="visuallyhidden">Horizontal</h2>
<div class="slide">1</div> <ul class="scroll-container">
<div class="slide">2</div> <li class="slide">1</li>
<div class="slide">3</div> <li class="slide">2</li>
<div class="slide">4</div> <li class="slide">3</li>
<div class="slide">5</div> <li class="slide">4</li>
<div class="slide">6</div> <li class="slide">5</li>
<div class="slide">7</div> <li class="slide">6</li>
<div class="slide">8</div> <li class="slide">7</li>
</div> <li class="slide">8</li>
</ul>
<button class="prev">❮</button> <button class="prev">❮</button>
<button class="next">❯</button> <button class="next">❯</button>
<div class="pagination"></div> <ul class="pagination"></ul>
</div> </section>
<div class="snappy-carousel" data-scroll-direction="y"> <section class="snappy-carousel" data-scroll-direction="y" aria-labelledby="horizontal-carousel-heading">
<div class="scroll-container"> <h2 id="horizontal-carousel-heading" class="visuallyhidden">Vertical</h2>
<div class="slide">1</div> <ul class="scroll-container">
<div class="slide">2</div> <li class="slide">1</li>
<div class="slide">3</div> <li class="slide">2</li>
<div class="slide">4</div> <li class="slide">3</li>
<div class="slide">5</div> <li class="slide">4</li>
<div class="slide">6</div> <li class="slide">5</li>
<div class="slide">7</div> <li class="slide">6</li>
<div class="slide">8</div> <li class="slide">7</li>
</div> <li class="slide">8</li>
</ul>
<button class="prev">❮</button> <button class="prev">❮</button>
<button class="next">❯</button> <button class="next">❯</button>
<div class="pagination"></div> <ul class="pagination"></ul>
</div> </section>
</main>
<!-- Javascript is only needed for pagination and buttons --> <!-- Javascript is only needed for pagination and buttons -->
<script src="dist/snappy.js" defer></script> <script src="dist/snappy.js" defer></script>
+25 -6
View File
@@ -9,6 +9,8 @@
cursor: grab; cursor: grab;
scroll-behavior: smooth; scroll-behavior: smooth;
scroll-snap-type: x mandatory; scroll-snap-type: x mandatory;
margin: 0;
padding: 0;
&.is-dragging { &.is-dragging {
scroll-snap-type: none !important; scroll-snap-type: none !important;
@@ -23,14 +25,20 @@
scroll-snap-stop: normal; scroll-snap-stop: normal;
} }
.pagination .dot { .pagination {
display: inline-block; margin: 0;
width: 1rem; padding: 0;
height: 1rem; list-style: none;
background-color: silver;
} }
.prev, .next { .pagination .dot {
width: 1rem;
height: 1rem;
border: none;
}
.prev,
.next {
touch-action: manipulation; touch-action: manipulation;
} }
@@ -54,4 +62,15 @@
&[data-snap-stop="always"] .slide { &[data-snap-stop="always"] .slide {
scroll-snap-stop: always; scroll-snap-stop: always;
} }
}
.visually-hidden {
border: 0;
clip-path: inset(50%);
height: 1px;
margin: 0;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
} }
+15 -5
View File
@@ -360,14 +360,21 @@ class Carousel {
createPagination() { createPagination() {
this.slides.forEach((slide, index) => { this.slides.forEach((slide, index) => {
// Populate the pagination container with dots for each slide // Populate the pagination container with dots for each slide
let div = document.createElement('div'); let li = document.createElement('li');
div.classList.add('dot'); let button = document.createElement('button');
div.addEventListener('click', () => this.goToSlide(index)); button.classList.add('dot');
this.pagination.appendChild(div); button.addEventListener('click', () => this.goToSlide(index));
let name = document.createElement('span');
name.textContent = "Slide " + (index + 1);
name.classList.add("visually-hidden");
button.appendChild(name);
li.appendChild(button);
this.pagination.appendChild(li);
// Store a reference to the pagination dots in the carousel object for later use // Store a reference to the pagination dots in the carousel object for later use
if (!this.paginationDots) this.paginationDots = []; if (!this.paginationDots) this.paginationDots = [];
this.paginationDots.push(div); this.paginationDots.push(button);
}); });
} }
@@ -449,6 +456,9 @@ class Carousel {
if (this.activeSlideIndex === this.renderedActiveSlideIndex) return; if (this.activeSlideIndex === this.renderedActiveSlideIndex) return;
this.renderedActiveSlideIndex = this.activeSlideIndex; this.renderedActiveSlideIndex = this.activeSlideIndex;
this.prevButton.disabled = this.activeSlideIndex <= 0;
this.nextButton.disabled = this.activeSlideIndex >= this.slides.length - 1;
this.slides.forEach((slide, index) => { this.slides.forEach((slide, index) => {
slide.classList.toggle('is-active', index === this.activeSlideIndex); slide.classList.toggle('is-active', index === this.activeSlideIndex);
}); });