R3.09.1name-role-state triad设计

名称、角色、状态缺一辅助技术就无法表达

别名: accessible name · role · state · 无障碍名称 · 名称角色状态 · Name Role Value

概念解释

辅助技术并不阅读像素。它查询无障碍树里每一个可交互节点上的三个槽:名称(accessible name)、角色(role)、状态(state / value)。名称是怎么称呼这个东西,角色是它属于哪类控件,状态是此刻处于哪一档。三者合成一条可被朗读、可被转盘收集、可被开关查询的表达;缺任何一槽,这条表达就残缺——只剩「按钮」却没有名字、有名字却进不了控件列表、能找到控件却听不出开还是关。

它回答的是树上这一节点「能不能被说完整」,不是「该不该用原生标签」或「DOM 顺序对不对」。视觉上看起来像按钮,并不能补上这三个槽。

机制

屏幕阅读器和语音控制走的是平台无障碍 API,不是渲染树。API 按平台规则计算名称(标签、aria-labelledbyaria-label、内部文本、title 的优先级链),再附上角色和当前状态。计算链在某一环断开,名称就是空的:图标按钮只有图形、输入框的可见标签没有用 for 或包装关联,朗读就退化成「按钮」「编辑框」。角色若对不上实际行为——能点的节点报成无角色的分组——转盘、触控探索和语音命令都找不到它。状态若没暴露(按下、展开、选中、禁用、当前值),用户只能听到控件在,听不到它变过。

三槽是同一条表达的三个字段,不是三种可选的增强。名称解决「叫什么」,角色解决「当什么用」,状态解决「现在怎样」。只补名称、不补状态,等于给了一张名片却不说门开着还是关着。

边界

静态只读文本没有交互状态可报,名称加角色(或直接作为文档文本)即可,不必硬造 aria-pressed。进度、滑块的「状态」是当前值,不是布尔开关,空值比错误值更糟。名称计算链因平台而异,桌面端 VoiceOver 与移动端 TalkBack 对同一 DOM 的名称优先级不完全相同,只在一种引擎上听过不能外推。装饰性图形本来就不该进树,给它名称会造成噪音,那是该不该暴露的问题,不是三槽缺一。

怎么落地

  • 对每个可交互控件列出三槽:看得见的称呼如何变成 accessible name、角色是否与行为一致、按下/展开/选中/禁用/当前值从哪一属性读出。
  • 图标按钮、无可见文字的开关、自定义选中项,用关联标签或 aria-label 补名称;有可见标签时优先关联,不要再盖一层不同措辞的 aria-label
  • 开关、手风琴、选项、进度必须在无障碍树上出现对应状态或数值,不能只靠颜色或图标切换。
  • 验证:打开无障碍树检查器,逐个对照名称、角色、状态是否非空且与视觉一致;再用一种屏幕阅读器走一遍主路径,确认转盘能按角色收集,且切换时能听到状态变化。

延伸

  • 同组R3.09.2 视觉隐藏与语义隐藏是两件事 · R3.09.3 动态变化需要主动播报而非只改样式
  • 相邻R3.01 语义结构 · J2.09 语义结构
  • 站内检索accessible name · role · state · name-role-state triad

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/R3.09.1