角色 复合控件
tree
将元素标记为由 treeitem 组成的层级容器——文件浏览器、嵌套分类或组织结构图。单 Tab 停止点,方向键导航,支持展开/折叠。无对应的原生 HTML 等效元素。
使用时机
适用于真正的层级浏览器:文件系统、组织结构图、深层嵌套分类体系。子元素使用 role="treeitem",必要时由中间层 role="group" 包裹分组。
若所谓”树”实质上是两到三级链接的导航菜单,不应使用 role="tree"。应改用带有嵌套 <ul> 和 <a> 的 <nav>——用户对导航操作的预期是 Tab + Enter;在网站菜单中使用方向键树形导航既陌生又低效。
树必须具有无障碍名称。若允许同时选中多个 treeitem,应设置 aria-multiselectable="true"。
键盘与焦点约定
按照 APG 树形视图模式:
- Tab 将焦点移入树,落在当前聚焦(或第一个)treeitem 上;再次按 Tab 移出树。
- 上/下方向键在可见节点间移动焦点,跳过已折叠的子节点。
- 右方向键:若已折叠则展开;若已展开则移至第一个子节点。
- 左方向键:若已展开则折叠;若已折叠则移至父节点。
- Home / End 移至第一个 / 最后一个可见节点。
- Enter 或 Space 选中当前 treeitem。
- 预输入:输入字母可跳至匹配的可见节点。
- 多选树:Shift+方向键扩展连续选区;Ctrl/Cmd+单击切换单项选中状态。
采用漫游 tabindex:仅当前聚焦的 treeitem 持有 tabindex="0"。
常见错误
- 每个 treeitem 均设置
tabindex="0"。该模式要求单 Tab 停止点。 - 树没有无障碍名称。屏幕阅读器在地标导航时无内容可宣告。
- 子 treeitem 位于父节点内,但缺少包裹的
role="group"。屏幕阅读器无法将该组作为整体宣告。 - 在叶节点 treeitem 上设置
aria-expanded="false"——宣告了一个空的可折叠状态。 - 将左/右方向键用于切换前后兄弟节点,而非展开/折叠操作。
示例
<ul role="tree" aria-label="项目文件">
<li role="treeitem" aria-expanded="true" tabindex="0">
src
<ul role="group">
<li role="treeitem" tabindex="-1">index.ts</li>
<li role="treeitem" aria-expanded="false" tabindex="-1">
components
<ul role="group">
<li role="treeitem" tabindex="-1">Button.tsx</li>
</ul>
</li>
</ul>
</li>
<li role="treeitem" tabindex="-1">README.md</li>
</ul>