feat(a11y): add keyboard prev/next to photo strip and region landmark

This commit is contained in:
2026-06-20 20:32:12 +02:00
parent ce5d520817
commit f463eadbef
2 changed files with 55 additions and 0 deletions
+26
View File
@@ -246,6 +246,32 @@ body::after {
background: var(--color-ink-muted); background: var(--color-ink-muted);
} }
.strip-controls {
display: flex;
justify-content: center;
gap: var(--space-3);
margin-top: calc(-1 * var(--space-2));
margin-bottom: var(--space-4);
}
.strip-prev,
.strip-next {
background: transparent;
border: 1px solid var(--color-border);
color: var(--color-ink-2);
border-radius: var(--radius-sm);
padding: var(--space-1) var(--space-3);
font-size: var(--text-md);
line-height: 1;
cursor: pointer;
}
.strip-prev:hover,
.strip-next:hover {
border-color: var(--color-accent);
color: var(--color-accent);
}
.journal-post-body { .journal-post-body {
font-size: var(--text-base); font-size: var(--text-base);
line-height: var(--leading-normal); line-height: var(--leading-normal);
@@ -30,13 +30,42 @@
<script> <script>
(function () { (function () {
document.querySelectorAll('.journal-photo-strip').forEach(function (strip) { document.querySelectorAll('.journal-photo-strip').forEach(function (strip) {
strip.setAttribute('role', 'region');
strip.setAttribute('aria-label', 'Photo strip');
var slideCount = parseInt(strip.dataset.slides, 10) || 1;
var dots = strip.nextElementSibling; var dots = strip.nextElementSibling;
if (!dots || !dots.classList.contains('journal-photo-dots')) return; if (!dots || !dots.classList.contains('journal-photo-dots')) return;
var dotEls = Array.from(dots.querySelectorAll('.journal-photo-dot')); var dotEls = Array.from(dots.querySelectorAll('.journal-photo-dot'));
strip.addEventListener('scroll', function () { strip.addEventListener('scroll', function () {
var idx = Math.round(strip.scrollLeft / strip.offsetWidth); var idx = Math.round(strip.scrollLeft / strip.offsetWidth);
dotEls.forEach(function (d, i) { d.classList.toggle('is-active', i === idx); }); dotEls.forEach(function (d, i) { d.classList.toggle('is-active', i === idx); });
}, { passive: true }); }, { passive: true });
if (slideCount < 2) return;
var prev = document.createElement('button');
prev.className = 'strip-prev';
prev.setAttribute('aria-label', 'Previous photo');
prev.textContent = '';
prev.addEventListener('click', function () {
strip.scrollBy({ left: -strip.offsetWidth, behavior: 'smooth' });
});
var next = document.createElement('button');
next.className = 'strip-next';
next.setAttribute('aria-label', 'Next photo');
next.textContent = '';
next.addEventListener('click', function () {
strip.scrollBy({ left: strip.offsetWidth, behavior: 'smooth' });
});
var controls = document.createElement('div');
controls.className = 'strip-controls';
controls.appendChild(prev);
controls.appendChild(next);
dots.insertAdjacentElement('afterend', controls);
}); });
})(); })();
</script> </script>