带计时功能的页面需兼顾可访问性:使用语义化标签(如、)、aria-live合理播报、提供键盘可操作的暂停/恢复控件、辅以文本状态提示,并确保所有状态变更同步更新dom与焦点。

带计时功能的页面(比如倒计时、自动刷新、限时答题、进度条)对屏幕阅读器用户和键盘/运动障碍用户极不友好——默认行为常导致焦点丢失、内容突变、无法暂停或感知剩余时间。核心解决路径是:用语义化结构表达时间状态 + 暴露可读文本 + 允许用户控制。
用 <time></time> 和 <progress></progress> 替代纯 div + JS 渲染
很多倒计时直接用 <div id="timer">00:42</div> 更新,屏幕阅读器既不知道这是时间,也无法播报变化。应优先使用原生语义标签:
-
<time datetime="PT42S">42 秒</time>—— 明确告诉辅助技术这是「剩余时间」,datetime值需为 ISO 8601 持续时间格式(如PT30M表示 30 分钟) - 进度类场景用
<progress value="65" max="100"></progress>,配合aria-label="上传进度:65%",比<div class="bar"> 可靠得多 <li>避免把 <code><span></span>或<div> 当计时器容器;若必须用,至少补 <code>role="timer"和aria-live="polite"动态更新必须配
aria-live,且选对 politeness 级别计时器每秒刷新,但屏幕阅读器不会自动读出新值,除非你明确声明它“值得播报”。错误做法是给整个容器加
aria-live="assertive"——会导致每秒打断用户当前操作。- 倒计时剩余秒数 → 用
aria-live="polite",让阅读器在空闲时播报(例如:“剩余 23 秒”) - 倒计时结束触发关键动作(如提交表单、跳转)→ 用
aria-live="assertive"+ 同步聚焦到新内容区域 - 禁止对同一元素反复设置
aria-live属性;应在初始渲染时就写好,JS 只更新文本内容 - 示例:
<div aria-live="polite" aria-atomic="true"><time datetime="PT17S">17 秒</time></div>
其中aria-atomic="true"确保整段文本被完整读出,而非只读“17”
必须提供暂停/恢复/重置控件,并确保键盘可访问
WCAG 2.1 要求所有自动更新内容(尤其是超过 5 秒的)必须允许用户暂停、停止或隐藏。这不只是加个按钮,而是要让它真正可用。
- 按钮必须是
<button></button>,不是<div onclick>;否则键盘用户无法聚焦、无法按空格/回车触发 <li>暂停后,计时器视觉上应明显变化(如灰显 + “已暂停”文字),且 <code>aria-busy="false"或aria-disabled="true"需同步更新 - 暂停按钮本身需有清晰
aria-label,如aria-label="暂停倒计时",避免仅用图标 - 若计时器嵌在模态框内,暂停按钮焦点顺序必须合理,不能被遮挡或 tabindex 错乱
- 在倒计时旁固定显示文本提示,如“时间紧迫,请尽快完成”“还剩最后 1 分钟”,不要只靠红字变深
- 进度条旁配文字说明:“已完成 80%,剩余约 2 分钟”
- 超时后,错误提示不能只靠弹窗或变色;必须用
role="alert"包裹,且焦点自动移入,例如:<div role="alert">答题时间已结束,已自动提交</div>
- 禁用 CSS 动画作为唯一时间指示器;如用
@keyframes做倒计时条,务必同步更新<progress></progress>的value属性
避免依赖视觉节奏,用文本+状态双重提示
仅靠闪烁、颜色渐变或动画快慢来传达时间压力,对色觉障碍、低视力或注意力障碍用户无效。
最难的部分不是加属性,而是让所有状态变更(暂停/恢复/超时/重置)都同步更新 DOM 属性、焦点位置和屏幕阅读器播报逻辑。漏掉任意一环,对依赖辅助技术的用户来说,这个“倒计时”就等于不可见、不可控、不可预测。
- 倒计时剩余秒数 → 用











