标准 · ARIA

角色 动态区域

status

一种传递非紧急建议性信息的动态区域。屏幕阅读器以礼貌模式播报变化——在当前语音停顿后插入,不打断正在进行的朗读。适用于常规确认、数量提示和进度更新。原生 <output> 元素自动具有该角色。

使用时机

适用于非紧急建议性消息,例如:“已保存”、“12 条结果”、“商品已加入购物车”、“正在连接……”。role="status" 等同于 aria-live="polite" 加上隐式的 aria-atomic="true"——屏幕阅读器等待当前语音结束后,再播报内容变化。

大多数表单提交成功提示、搜索结果计数、加载完成通知以及 toast 提示均属于此类场景。请将 role="alert" 保留给真正需要打断的情况。

原生 <output> 元素自动具有 role="status",适合与 <form> 输入框配合使用的计算器式结果展示。在表单上下文之外的 toast 和状态通知场景中,<div role="status"> 是标准模式。

与所有动态区域一样,状态元素必须在消息插入之前已存在于 DOM 中。应先渲染空的 <div role="status"></div>,再通过更新文本内容触发播报。若在元素创建时就将内容放入其中,播报可靠性无法保证。

动态区域的权衡

  • aria-live="off" — 不播报。普通内容的默认行为。
  • aria-live="polite"(等同于 role="status")— 在下一次停顿时播报。状态消息的默认选择。
  • aria-live="assertive"(等同于 role="alert")— 中断当前语音。仅用于紧急消息。

WCAG 4.1.3(状态消息,AA 级)要求状态消息通过动态区域暴露,以便辅助技术在不强制切换焦点的情况下播报这些消息。

常见错误

  • 动态创建状态元素时,内容已预先填入——许多屏幕阅读器会错过此次播报。
  • 在状态内容中使用标记(<span><strong> 等)——部分屏幕阅读器会逐字读出标签;请保持状态内容为纯文本。
  • 快速连续更新——后续消息覆盖前一条,前一条可能未被播报。
  • 对真正的紧急错误使用 role="status"(应改用 role="alert")。
  • 视觉隐藏的状态区域在包含稳定部分与变化部分的混合内容时,未考虑 aria-atomic 的影响——role="status" 默认的 aria-atomic="true" 会在每次变化时读出整个区域,可能造成冗余播报。

示例

<!-- 页面加载时渲染为空 -->
<div role="status" id="cartStatus"></div>

<script>
  // 购物车更新时:
  document.getElementById('cartStatus').textContent =
    'Added to cart. 3 items, $42.00 total.';
</script>

<!-- 原生等效写法 -->
<form>
  <label>a <input type="number" id="a"></label>
  <label>b <input type="number" id="b"></label>
  <output for="a b" id="sum">0</output>
</form>