role="combobox"不能替代,需手动实现展开逻辑、焦点管理、aria属性同步(aria-expanded、aria-controls、aria-autocomplete等)、键盘交互(arrowdown/up/enter/escape)及状态一致性,否则可访问性失效。

combobox role 不能直接当 select 用
HTML 的 role="combobox" 不是 <select></select> 的替代品,它描述的是“可编辑 + 可展开列表”的复合控件行为(比如带搜索的下拉),浏览器不会自动给你渲染下拉面板或绑定键盘导航。你得自己实现展开逻辑、焦点管理、Aria 属性同步 —— 否则只是个语义空壳,对屏幕阅读器无效,也破坏可访问性。
必须配 aria-expanded 和 aria-controls
仅设 role="combobox" 是不够的。关键配套属性缺一不可:
-
aria-expanded要实时反映下拉是否打开("true"或"false") -
aria-controls必须指向下拉列表容器的id,让辅助技术知道两者关联 - 输入框需有
aria-autocomplete="list"(表示补全来源是固定列表) - 下拉容器必须设
role="listbox",每个选项用role="option",并用aria-selected标记当前选中项
漏掉任意一个,NVDA/JAWS 就无法正确播报状态或支持方向键导航。
键盘交互必须手动实现
原生 <select></select> 自带 ArrowDown/Enter/Escape 行为,但 role="combobox" 没有。你得监听:
-
ArrowDown:打开下拉,并把焦点移到第一个role="option" -
ArrowUp:在已展开时向上导航,Escape关闭下拉并返回输入框 -
Enter或Space:确认当前高亮项并关闭下拉 -
Tab:离开时需确保焦点顺序合理(通常跳过列表,除非显式聚焦)
没处理这些,键盘用户就卡死在输入框里,完全无法操作下拉项。
别忽略 focus management 和 aria-activedescendant
如果不想把焦点真的移到每个 role="option"(比如要保持输入框始终可编辑),就得用 aria-activedescendant 指向当前高亮项的 id,同时手动管理视觉高亮样式。否则:
- 焦点留在输入框,但屏幕阅读器不知道哪个选项被高亮
- 按
Enter时无法确定用户想选谁 - 移动端双击可能触发错误的焦点切换
这个模式比直接移焦更复杂,但对带搜索的 combobox 更友好 —— 它允许用户边打字边用方向键预览,不中断输入流。
真正难点不在写 HTML,而在同步状态:输入值、展开状态、高亮项、选中项、焦点位置、aria 属性,五者必须严格一致。稍有不同步,辅助技术就会读错或跳过内容。动手前先想清楚交互流程,再逐项补全 ARIA 链路,比堆 markup 重要得多。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











