补充属性无法给元素添加它本身不具备的键盘交互行为
别名: ARIA 无键盘 · role=button 无按键 · 语义不是行为
概念解释
给 div 写 role="button" 或 role="slider",无障碍树会按按钮、滑块来介绍它。键盘不会因此出现。Enter、空格、方向键、Home/End 仍是宿主元素原来那一套——div 默认什么都不做。补充属性不加键盘行为(ARIA does not add keyboard behavior):ARIA 改的是语义映射,不是事件监听。角色合同里那些按键,要作者自己写,或者换一个本来就会这些键的元素。
这不是选型口号,是管道分工:语义一条管,行为一条管,没有桥。
机制
用户代理为原生控件注册了按键。<button> 在 Enter 和空格上分发激活;<input type="range"> 吃方向键改值;<select> 吃字符跳转。ARIA 角色不进入这条注册表。阅读器在焦点模式下把键交给控件,控件的监听器若是空的,键就落到页面滚动或被浏览模式截走。树上的角色越完整,预期越具体,空监听造成的落差越大:用户按空格,以为按下了开关,页面却翻了一屏。
第二层是焦点。许多原生控件默认可聚焦;div 不是。只写角色、不写 tabindex,键盘用户连到达都做不到,更谈不上按键合同。写了 tabindex="0" 只解决到达,仍不产生激活。作者常以为「检查器里角色对了就是可操作」,检查器从不测试空格有没有监听器。
怎么研究
做一对控件:原生按钮;带 role="button" 的 div(分两档:无 tabindex、仅有 tabindex、以及自己监听了 Enter/空格)。键盘-only 走一遍:能否 Tab 到、空格/Enter 是否触发、阅读器焦点模式下按键被谁消费。滑块、选项卡、菜单各做同样的「只加角色 / 加角色且手写键盘」对照。NVDA 焦点模式与 VoiceOver「与控件交互」都要测,因为交键的时机不同。
自变量:宿主是否原生、是否可聚焦、是否有键盘监听、角色种类。 因变量:到达、激活、值改变、按键是否冒泡成页面滚动。
边界
部分框架或设计系统会在检测到某些角色时自动绑键盘,看起来像「ARIA 生效了」,其实是脚本补上的行为,换一个没接这套运行时的环境就会消失。触控和指针不经过这条合同:鼠标点 div 上的点击监听可以成功,键盘仍是空的,所以用鼠标测过不能当键盘证据。浏览模式下阅读器自己的快捷键(H、B)不是控件行为,不能拿「H 能跳到这个标题」证明 role="button" 的 div 可激活。
怎么落地
- 需要按钮、链接、滑块、选项卡的键盘合同,先用宿主元素;自定义时把 Enter/空格/方向键写进组件,并写进测试,不要停在
role。 tabindex只解决到达。到达之后仍要用键盘跑一遍激活和改值。- 不要把「检查器角色正确」当成可操作;可操作的判据是键被控件消费并且状态改变。
- 验证:拔掉鼠标,Tab 到该控件,按空格和 Enter,再按角色合同里该有的方向键。什么都没发生或页面在滚,就是语义已经换了、行为还是
div。再用 NVDA 切入焦点模式重复一次,排除浏览模式截键的假阳性。