标准 · ARIA

属性 关系

aria-activedescendant

在复合构件上,指向当前处于激活状态的后代元素的 ID。DOM 焦点保持在容器上,虚拟焦点在子元素间移动。是列表框、组合框和网格采用漫游 tabindex 方案的替代方式。

适用场景

适用于复合构件:需要保留单一 Tab 停留点,同时允许用户在多个条目间移动高亮焦点的场景——例如带有列表框弹出层的组合框输入框、单 Tab 停留点的列表框、树形网格、数据网格。DOM 焦点始终保持在容器元素(输入框、列表框、网格)上。用户按方向键时,将 aria-activedescendant 更新为新高亮子元素的 ID,辅助技术会像焦点真正移入该元素一样读出其内容。

另一种模式是漫游 tabindex:实际移动 DOM 焦点并调整各元素的 tabindex 值。当保持浏览器焦点在容器上能简化代码时(通常是因为容器同时承担用户输入或键盘快捷键的绑定),选用 aria-activedescendant

行为说明

该属性的值为单个元素 ID,不能是列表。被引用的元素必须是带有 aria-activedescendant 属性的容器的后代(或通过 aria-owns 归属)。值更新后,辅助技术树中”虚拟焦点”的位置移至该元素,辅助技术随即读出其标签、角色和状态。

以下两点仍由开发者负责:

  • 视觉样式。辅助技术知晓虚拟焦点的位置,但浏览器不会在后代元素上绘制焦点环。需要通过同步切换 class 的方式添加自定义高亮样式。
  • 滚动。若激活的后代元素不在可视区域内,必须以代码将其滚动至视口;浏览器不会自动处理。

弹出层关闭或构件失去焦点时,应将 aria-activedescendant 清空为空字符串或移除该属性。

常见错误

  • 指向的 ID 并非容器的后代(也未通过 aria-owns 归属)。辅助技术会忽略该引用。
  • 模式混用:在后代元素上设置 tabindex="0" 的同时,又在容器上设置 aria-activedescendant。两种焦点策略只能选其一,同时使用会相互冲突。
  • 属性更新后忘记同步更新视觉高亮——有视力的用户看不到移动,而辅助技术用户却已听到焦点变化的提示。
  • 选项从列表中移除后(例如组合框筛选结果),遗留过期的 ID。
  • 鼠标悬停时更新 aria-activedescendant。该属性应仅跟踪键盘驱动的激活条目。
  • 在辅助技术树中不包含后代元素的元素上设置该属性(忘记为传送门渲染的列表添加 aria-owns)。

示例

<label for="fruit">Fruit</label>
<input
  id="fruit"
  role="combobox"
  type="text"
  aria-controls="fruit-listbox"
  aria-expanded="true"
  aria-activedescendant="fruit-2"
  autocomplete="off"
>
<ul id="fruit-listbox" role="listbox">
  <li id="fruit-1" role="option">Apple</li>
  <li id="fruit-2" role="option" class="is-active">Banana</li>
  <li id="fruit-3" role="option">Cherry</li>
</ul>