角色 动态区域
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>