组织架构图必须使用语义化树结构而非表格,采用 role="tree" 的嵌套列表,配合 aria-expanded、aria-hidden 和 aria-labelledby 确保层级关系、可聚焦性与屏幕阅读器正确播报。

组织架构图不能用纯表格模拟
用 <table> 嵌套多层 <tr><td> 模拟树状结构,屏幕阅读器会按行列顺序线性播报,完全丢失“CEO → CTO/CMO → 工程组/市场组”这种父子关系。用户听到的是一串无序的职位名,无法建立层级认知。
常见错误是给每个 <td> 加 aria-level 或 role="treeitem",但浏览器不识别这些属性在表格上下文中的语义,反而可能触发冗余播报或跳过关键节点。
- 真正有效的结构是放弃表格,改用语义化列表 + 显式角色
- 每个部门/岗位必须包裹在
<li>中,且父级<ul>或<ol>需设role="tree" - 每个节点用
<button>或带tabindex="0"的<div>包裹,确保键盘可聚焦
用 role="tree" + aria-expanded 控制展开态
动态折叠/展开的组织图,仅靠 CSS visibility 或 height 动画无法被屏幕阅读器感知。必须用 aria-expanded 显式声明状态,并同步控制子节点的 aria-hidden。
例如点击“技术部”展开时,需同时:设置该节点 aria-expanded="true";其子 <ul> 移除 aria-hidden="true";若收起,则子列表加 aria-hidden="true" 且自身设为 aria-expanded="false"。
立即学习“前端免费学习笔记(深入)”;
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
-
aria-expanded必须与视觉状态严格同步,JS 更新 DOM 后立即更新该属性 - 不要用
display: none隐藏子节点——它会强制移除可访问性树节点,导致焦点丢失 - 收起状态下,子节点仍保留在 DOM 中,仅通过
aria-hidden="true"屏蔽
每个节点必须有唯一 id 并用 aria-labelledby 关联上下文
单纯写 <span>前端工程师</span>,屏幕阅读器只会读“前端工程师”,用户不知道这是属于“Web 团队”还是“移动端团队”。必须用 aria-labelledby 将当前节点与上级标题显式绑定。
例如“高级前端工程师”节点:<li id="dev-senior-fe"><div aria-labelledby="team-web dev-senior-fe">高级前端工程师</div></li>,其中 id="team-web" 是“Web 团队” <h3> 的 ID。
- 多个 ID 用空格分隔,顺序决定播报优先级(先读上级标题,再读本职名称)
- 避免用
aria-describedby—— 它只播报一次,无法在焦点移动到不同工程师时持续提供归属信息 - 所有用于关联的 ID 必须真实存在且唯一,否则部分屏幕阅读器会静默失败
键盘导航必须支持方向键而非仅 Tab
仅靠 Tab 键在几十个节点间跳转,效率极低。真正的组织架构图需要支持 ↑/↓ 切换同级、←/→ 折叠/展开、Home/End 跳首尾——这依赖 role="tree" 的原生行为,但前提是结构合规。
- 根节点(如 CEO)必须设
role="treeitem"且是<ul role="tree">的直接子元素 - 子节点层级必须严格嵌套:
<li><div role="treeitem">...</div><ul>...</ul></li>,不能跳级 - 每个
role="treeitem"必须包含可聚焦元素(<button>或tabindex="0"的容器),否则方向键无法停驻
最易被忽略的是:如果用了 <section> 或 <article> 包裹某一层级,会打断 role="tree" 的继承链,导致方向键失效。结构必须干净,只保留 <ul>/<li>/<div> 和必要角色属性。


















