- Success Criterion 4.1.3
- Conformance level AA
Countdown Timer Update Shown Visually but Never Announced
4.1.3 — Status Messages
Scenario
Setting
A budget airline's flight search results
What’s wrong
Countdown/timer status text (resend-one-time password (OTP) timers, session countdowns) updating visually only.
Example
<p id="fareTimer">Fare held for 9:58</p>
// JS: setInterval runs every 1000ms and sets fareTimer.textContent = `Fare held for ${formatTime(--secondsLeft)}`
<!-- the timer text rewrites every second, with no aria-live, and updating that often would
overwhelm speech output even if it had one --> Why it matters
A traveler using a screen reader has no sense of the fare hold expiring, and could lose the price mid-booking with no warning.
How to test
Watch a countdown/timer (e.g., resend-OTP, session countdown) with a screen reader running: if the changing time isn't announced, it fails.
How to fix
Announce a fast-changing countdown at a few key milestones instead of every second.
<p id="fareTimer">Fare held for 9:58</p>
<p id="fareTimerAlert" role="status" aria-live="polite" class="visually-hidden"></p>
<!-- only write to fareTimerAlert at milestones: "2 minutes left to book this fare", "30 seconds left" --> Outcome
A traveler hears "2 minutes left to book this fare" and completes the purchase in time.
Who is affected
Screen reader users booking a held fare get no timely warning before the countdown runs out.
Learn more
- Understanding Understanding document (opens in a new tab)
Related scenarios
- Status Update Shown Visually but Never Wired for Screen Readers
- Cart Confirmation Toast With No Live Region Announcement
- Search Result Count That Updates Silently on Every Filter
- Autosave ‘Saved’ Indicator With No Live Announcement
- Loading Spinner With No Programmatic Busy or Status State
- Error Toast With No Alert Role and No Focus Movement