标准 · ARIA

属性 关系

aria-owns

当 DOM 结构无法表达父子关系时,在无障碍树中声明该关系,将被引用元素作为当前元素的子项重新归属,供辅助技术使用。这是一个强力工具,容易误用。

使用时机

仅当 DOM 无法将子元素放置在无障碍树所需位置时使用。最常见的场景是 combobox 的弹出 listbox:该列表因层叠上下文原因位于 <body> 末尾,但语义上属于 combobox。在 combobox 上使用 aria-owns 并指向 listbox 的 ID,可告知辅助技术将 listbox 视为其子项。

若能重构 DOM 使子元素成为真正的后代,应优先采用该方式。aria-owns 是应急手段——虽然有效,但它绕过了作者在标记与语义一致性方面最自然的检验机制。

行为说明

其值为以空格分隔的元素 ID 列表。无障碍树将按列出的顺序,把每个被引用元素重新归属为当前元素的子项,原 DOM 父级在无障碍树视图中将失去这些子项。

保持树结构有效的规则:

  • 每个被引用的 ID 必须存在且唯一。
  • 同一元素在同一时刻只能被一个父级通过 aria-owns 归属。若两处同时归属同一元素,行为未定义。
  • 不得将自身的祖先元素作为归属目标,否则会在无障碍树中形成循环。
  • 被归属元素在 DOM 中仍须可达——允许 display: none,但完全游离于文档之外的元素不可归属。

常见错误

  • 指向的 ID 不存在或在最新渲染中已被移除。
  • DOM 本可直接嵌套子元素时仍使用 aria-owns,徒增复杂度。
  • 两处 aria-owns 均引用同一子元素——辅助技术会任意选择其中一个。
  • 忘记焦点顺序与 aria-owns 无关:键盘仍按 DOM 的视觉顺序切换焦点,aria-owns 仅影响屏幕阅读器遍历无障碍层级的方式。
  • 试图借助 aria-owns 解决焦点或滚动定位问题——它对两者均无效。
  • 将某个区域归属为自身的拥有者,形成循环,破坏树结构。

示例

<!-- Combobox,其弹出层因层叠上下文被传送至 body -->
<div
  role="combobox"
  id="city-cb"
  aria-haspopup="listbox"
  aria-expanded="true"
  aria-owns="city-listbox"
>
  <input type="text" aria-controls="city-listbox" aria-activedescendant="city-opt-2">
</div>

<!-- listbox 位于 body 末尾,语义上归属于 combobox -->
<ul role="listbox" id="city-listbox">
  <li role="option" id="city-opt-1">London</li>
  <li role="option" id="city-opt-2" aria-selected="true">Paris</li>
</ul>