WCAG 2.2.1 · Level A · ADA Title II

Time limits and the ADA

Appointment holds and session timeouts can shut people out. For each limit, WCAG 2.2.1 needs one of three fixes: turn off, adjust, or extend after a warning.

When the clock runs out on the user

A person using a screen reader, a switch or voice control often needs more time to read, fill in and submit a form. A person with a cognitive disability may need time to find a document. A fixed, silent timeout turns that into a failed task.

Success Criterion 2.2.1 applies to each time limit set by the content. At least one of these must be true:

  • Turn off: the user can turn the limit off before meeting it.
  • Adjust: the user can change it before meeting it, to at least ten times the default.
  • Extend: the user is warned before time runs out, gets at least 20 seconds to extend it with a simple action, and can do that at least ten times.

Three exceptions apply: a limit required by a real-time event with no alternative, such as an auction; a limit that is essential, where extending would invalidate the activity; and limits longer than 20 hours. Only limits set by the content count, and server-side timeouts under the author's control are included.

Limits that appear on public service sites

  • A DMV appointment page that holds a slot for five minutes.
  • A court e-filing session that expires while a document uploads.
  • A utility bill payment page that times out after a few idle minutes.
  • A notice that disappears after a few seconds and carries a confirmation number.

These are the pages where a missed deadline has real cost: a lost slot, a rejected filing, a payment that did not go through. The extension must be reachable from the keyboard and announced to screen readers, not just shown as a visual countdown.

Warn and extend a slot hold

The simplest compliant pattern is a warning with a button that extends the hold. Here a hold lasts five minutes and the warning appears with one minute left, which is more than 20 seconds. It can be repeated.

Incorrect
setTimeout(releaseSlot, 5 * 60 * 1000);   // silent release
Correct
const HOLD_MS = 5 * 60 * 1000, WARN_MS = 60 * 1000;
let warnTimer, releaseTimer;

function scheduleWarning() {
  warnTimer = setTimeout(() => {
    holdWarning.hidden = false;           // role="alert" container
    releaseTimer = setTimeout(releaseSlot, WARN_MS);
  }, HOLD_MS - WARN_MS);
}
extendBtn.addEventListener("click", async () => {
  clearTimeout(releaseTimer);
  holdWarning.hidden = true;
  await extendHold();                     // server adds 5 more minutes
  scheduleWarning();                      // may be repeated
});
scheduleWarning();

Let people turn the limit off up front

When the time limit comes from the application rather than from a security need, an option on the first screen is the strongest answer, because no warning is needed at all.

Incorrect
<p>You have 10 minutes to finish this enrollment form.</p>
Correct
<form action="/enroll/start" method="post">
  <label>
    <input type="checkbox" name="no_time_limit">
    I need more time: remove the time limit for this application
  </label>
  <button type="submit">Start enrollment</button>
</form>

Notices that vanish

An auto-dismissed toast is a time limit on reading. If it carries information the user needs, keep it on screen until it is dismissed or make the same information available elsewhere.

Incorrect
setTimeout(() => toast.remove(), 3000);   // permit number gone
Correct
toast.innerHTML =
  'Permit PRM-4471 filed. <button type="button" id="t-close">Dismiss</button>';
document.getElementById("t-close").addEventListener("click", () => toast.remove());
// Also shown on the application status page.

Timers in mobile apps

A hold in a ticketing or booking app has the same problem. The warning must be exposed to VoiceOver and TalkBack, not only drawn.

SwiftUI:

Incorrect
.onReceive(timer) { _ in
    if remaining <= 0 { releaseSlot() }
    remaining -= 1
}
Correct
.onReceive(timer) { _ in
    remaining -= 1
    if remaining == 60 { showExtend = true }
    if remaining <= 0 { releaseSlot() }
}
.alert("Your reservation expires in 1 minute", isPresented: $showExtend) {
    Button("Keep my spot") { extendHold(); remaining += 300 }
}

Jetpack Compose:

Incorrect
LaunchedEffect(Unit) {
    delay(5 * 60 * 1000L)
    releaseSlot()
}
Correct
var deadline by remember(holdId) {
    mutableStateOf(System.currentTimeMillis() + 5 * 60 * 1000L)
}
// Keyed on deadline: extending moves it, which restarts this effect
LaunchedEffect(deadline) {
    delay(deadline - 60 * 1000L - System.currentTimeMillis())
    showExtend = true
    delay(60 * 1000L)
    releaseSlot()
}
if (showExtend) {
    AlertDialog(
        onDismissRequest = {},
        title = { Text("Your reservation expires in 1 minute") },
        confirmButton = {
            TextButton(onClick = {
                extendHold(); deadline += 5 * 60 * 1000L; showExtend = false
            }) {
                Text("Keep my spot")
            }
        }
    )
}

How to test and what goes wrong

  1. Find every timeout: search the code for setTimeout, setInterval, meta http-equiv="refresh", session lifetime settings and slot-hold logic.
  2. For each one, start the task and wait. Is there a warning, how long does it last, and can it be extended with the keyboard?
  3. Extend it ten times and check that the tenth works.
  4. Check that a screen reader announces the warning without moving the user away from what they were typing.

Common mistakes: a warning shown for 10 seconds, an extend button that works only once, a visual countdown with no announcement, and calling a limit "security" without checking whether it can be extended safely. Security limits can be essential, but that has to be true, not assumed.

The ADA angle and a ship-it list

Agencies often inherit timeouts from the vendor platform and assume they cannot be changed. Ask the vendor for configurable limits before accepting that.

Ship it when:

  • Each limit can be turned off, adjusted to ten times the default, or extended after a warning of at least 20 seconds.
  • The extension works at least ten times.
  • The warning is announced and reachable by keyboard.
  • Information in disappearing notices is also available elsewhere.

Related reading: vendors and third-party content.

Sources

Standard version: WCAG 2.1 (W3C Recommendation, 5 June 2018), as named in the Title II web rule. This page is for informational purposes only and is not legal advice. For binding requirements, refer to the official ADA statute and regulations, and ask a lawyer how they apply to you.

Corpowid is recognized by Gartner

Corpowid has been recognized by Gartner, a leading global research and advisory firm, for our innovation and performance in digital accessibility. These badges reflect our commitment to creating inclusive, AI-powered web experiences.

Have questions about Corpowid?

Let’s connect.

We will get back to you as soon as possible.