-
Notifications
You must be signed in to change notification settings - Fork 0
Description
PR Review - Accessibility Issues
1. Decorative characters announced by screen readers
Several decorative characters throughout the page will be read aloud by screen readers, creating a confusing experience for users relying on assistive technology.
Affected locations:
Line 17 - Subtitle:
> <span id="subtitle">Initialising system...</span><span class="animate-pulse">_</span>The > prefix and _ cursor are purely decorative but will be announced as "greater than" and "underscore".
Line 31 - Sponsor button:
<span id="sponsor-text">< BECOME A SPONSOR /></span>The < and /> will be read as "less than" and "slash greater than".
Line ~97 (JS) - Copied feedback:
sponsorText.innerText = '[ EMAIL COPIED! ]'Brackets will be announced as "left bracket" and "right bracket".
Suggested fix
Wrap decorative characters in elements with aria-hidden="true" to hide them from screen readers:
<!-- Line 17 - Subtitle -->
<h2 class="mt-4 text-xl md:text-2xl text-green-400 font-mono h-8">
<span aria-hidden="true">> </span><span id="subtitle">Initialising system...</span><span aria-hidden="true" class="animate-pulse">_</span>
</h2>
<!-- Line 31 - Sponsor button -->
<span id="sponsor-text">
<span aria-hidden="true">< </span>BECOME A SPONSOR<span aria-hidden="true"> /></span>
</span>For the JavaScript part, you'll need to preserve the structure when updating the text:
// Around line 97 - Update to preserve aria-hidden spans
sponsorBtn.onclick = async () => {
try {
await navigator.clipboard.writeText('sponsors@2026.es.pycon.org')
const originalHTML = sponsorText.innerHTML
sponsorText.innerHTML = '<span aria-hidden="true">[ </span>EMAIL COPIED!<span aria-hidden="true"> ]</span>'
setTimeout(() => {
sponsorText.innerHTML = originalHTML
}, 2000)
} catch (err) {
console.error('Failed to copy', err)
window.location.href = 'mailto:sponsors@2026.es.pycon.org'
}
}2. Respect prefers-reduced-motion for animations
What is prefers-reduced-motion?
prefers-reduced-motion is a CSS media query that detects if the user has requested the operating system to minimise non-essential motion. Users enable this setting for various reasons:
- Vestibular disorders (can cause dizziness, nausea, or disorientation)
- Motion sensitivity
- Cognitive conditions where motion is distracting
- Personal preference
It has two values:
no-preference- User hasn't indicated a preferencereduce- User prefers reduced motion
Where to apply it in this project:
A) The matrix/glitch effect on <h1> (lines 48-70)
This effect rapidly changes characters, which can be disorienting.
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
const init = () => {
const h1 = document.querySelector('h1')
// ...existing code...
if (h1) {
if (!prefersReducedMotion) {
runMatrixEffect(h1)
h1.onmouseover = () => runMatrixEffect(h1)
}
// If reduced motion is preferred, the text just appears instantly (no effect needed)
}
// ...existing code...
}B) The pulsing cursor animation (line 17)
The animate-pulse class creates a continuous blinking effect.
/* In global.css or a <style> tag */
@media (prefers-reduced-motion: reduce) {
.animate-pulse {
animation: none;
}
}Or using Tailwind's built-in support:
<span aria-hidden="true" class="animate-pulse motion-reduce:animate-none">_</span>Originally posted by @ctrl-alt-d in #16 (review)