概念

无障碍树

另见: a11y tree, accessibility object model, AOM

浏览器和操作系统基于 DOM 构建的内部数据结构,将每个元素映射为角色、名称、状态和关联关系——屏幕阅读器及其他辅助技术实际遍历的正是这份数据。

无障碍树是屏幕阅读器及其他辅助技术实际使用的操作系统级数据结构。当浏览器打开一个页面时,会构建两棵树:DOM 树(常规 HTML 层级结构)和无障碍树——一个从 DOM 衍生但包含无障碍元数据的并行结构。

理解无障碍树,可以解释约80%的 ARIA 行为谜题、屏幕阅读器行为及”为什么没有播报?“等调试困惑的根源。

组成内容

无障碍树中的每个节点包含:

  • 角色(Role)——元素是什么:按钮、链接、标题、导航、对话框。来自 HTML 元素类型或显式 ARIA role="..."
  • 名称(Name)——元素叫什么。来自标签文本、alt 属性、aria-labelaria-labelledby 或计算后的文本内容。
  • 描述(Description)——附加上下文。来自 aria-describedbytitle 属性。
  • 状态(State)——当前状态:已按下、已展开、已选中、加载中。来自 HTML 属性(disabledrequired)或 ARIA(aria-pressedaria-expanded)。
  • 属性(Properties)——关联关系与元数据:aria-controlsaria-ownsaria-haspopup

屏幕阅读器遍历这棵树,并根据上述字段播报每个节点。Tab 键和方向键导航也是沿无障碍树路由,而非沿 DOM 树路由。

纯视觉内容为何消失

一个 <div onclick="...">样式模拟按钮的元素</div> 在无障碍树中没有角色——浏览器将其视为普通 <div>,记录为 role="generic"(对辅助技术实际上是不可见的)。onclick 处理程序不会进入无障碍树,因为无障碍树只反映浏览器根据元素 HTML 角色推断其身份的结果。

这正是语义化 HTML 在最基础层面至关重要的原因:不是出于风格或惯例,而是因为语义化 HTML 元素会自动以正确角色填充无障碍树。非语义标记会产生屏幕阅读器无法理解的”div 汤”树。

ARIA 在树中的作用

ARIA 的存在恰恰是为了在原生 HTML 没有匹配元素时填充无障碍树。role="combobox" 告知浏览器为原本会显示为 generic 的元素在树中写入 combobox 节点;aria-expanded="true" 则在该节点上设置状态属性。

ARIA 不会改变 DOM,它改变的是浏览器写入无障碍树的内容。

如何检查

浏览器开发者工具现在可以直接显示无障碍树:

  • Chrome / Edge 开发者工具——元素面板 → 无障碍选项卡(右侧列)显示所选节点的计算无障碍属性。“完整页面无障碍树”切换(某些版本中通过 Chrome 标志启用)以侧边栏形式展示整棵树。
  • Firefox 开发者工具——无障碍面板(工具栏图标)提供专用的无障碍树视图,类似元素视图,但以无障碍树术语呈现。
  • Safari 网页检查器——审计/无障碍选项卡提供类似的检查功能。

能够直接查看无障碍树,就能从实证角度回答”为什么没有播报?“这一问题。答案几乎总是:无障碍树中该节点的角色与预期不符,或其名称为空,或其状态有误。

为何”无障碍树”比”ARIA”更好的心智模型

只学 ARIA 而不理解无障碍树的工程师,往往会随意添加 ARIA 属性,寄希望于屏幕阅读器能识别。而理解无障碍树的工程师则清楚:ARIA 的工作是向特定树节点写入特定字段,直接检查无障碍树比盲目猜测效率更高。