视觉可见的文字与实际计算出的可访问名称可能不一致
别名: 名称不一致 · label in name · 可见文字与计算名
概念解释
按钮上印着「下一步」,阅读器却说「继续」或「button」。可见文字与计算名不一致(accessible name mismatch)指的就是这件事:眼睛读到的字符串,和 AccName 算出来、写进无障碍树的那一串,不是同一个。不一致不是算法坏了,是两条管道喂了不同的料——可见文字走绘制,计算名走属性与隐藏节点。
它不是「名称、角色、状态要凑齐」的口号。角色可以正确、状态可以齐全,名字仍然可以对不上用户正在看的那几个字。
机制
覆盖一旦发生,可见文字就不再是名称的来源。aria-label 写成英文内部代号、labelledby 指到一段开发用的隐藏文案、图标字体把可见「文字」变成伪元素、CSS content 生成的字进了画面却常常进不了计算。反向也成立:可见区域是图标,计算名靠 aria-label 活着,两者本就不打算相同;危险的是作者以为它们相同。
第二层落在用户策略上。阅读器用户按计算名建立心智模型;能看见屏幕的人(放大、语音控制、对照着读的低视力用户)按可见文字发指令、做核对。两串字对不上,同一控件在两种策略里变成两个东西。语音控制尤其脆:用户朗读屏幕上的词,系统在计算名里找不到匹配。
怎么研究
做一张「可见 vs 计算」对照表,不要只听阅读器。对每个交互控件记录:截图上的字、无障碍面板的 Computed Name、NVDA 语音、用系统语音控制朗读可见文字能否命中。重点找三类:图标按钮、有 aria-label 的链接、可见文字被 CSS 截断或替换的菜单项。
自变量:覆盖是否存在、可见文字是否含在计算名中(label-in-name)、伪元素/图标字体。 因变量:名称字符串是否相等、语音控制命中率、用户口头复述时用的是哪一串。
边界
有意的补充不算失败:可见「12」旁边计算名是「12 件,购物车」,只要可见子串还在计算名里。纯图标、无字控件必须靠计算名活着,这时「不一致」是设计,不是缺陷——缺陷是计算名空洞或写成 icon-btn-32。国际化下可见文字与 aria-label 漏翻会在一种语言里对齐、另一种里分裂。画布上的字既不是可见 DOM 文本也不是名称来源,对照表两边都会空。
怎么落地
- 看得见的词应当作为计算名的子串出现;覆盖时把可见词写进
aria-label或labelledby所指向的文本,不要另起一套内部代号。 - 禁止用 CSS 伪元素或图标字体充当唯一可见标签,还指望计算名自动跟上。
- 图标按钮的可见提示(tooltip、邻接文字)与
aria-label用同一句话,而不是「界面中文、属性英文」。 - 验证:列一张表,左列截图文字,右列 Computed Name。不相等的行再拿 Voice Control / Voice Access 读左列,看点不中。点不中或阅读器念出另一套词,就是名称已经和画面分家。