aria-autocomplete="list"是combobox的默认安全选择,表示用户仅通过选择列表项更新值;必须配aria-expanded和aria-controls;禁用autocomplete属性避免干扰;需严格同步状态与焦点。

aria-autocomplete="list" 是 combobox 的默认安全选择
绝大多数可输入下拉场景,aria-autocomplete 必须设为 "list",而不是 "both" 或 "inline"。它不表示“要不要补全”,而是明确告诉辅助技术:“用户只能通过点击/键盘选择列表项来改变值,输入框本身不会被自动修改”。
-
aria-autocomplete="list":输入框内容由用户完全控制,选中项后才更新值;屏幕阅读器播报“已选择 X”,逻辑清晰、状态可控 -
aria-autocomplete="both":要求输入时实时插入字符(如 Chrome 地址栏),需手动处理光标位置、input与keydown冲突、覆盖用户输入等,极易出错 -
aria-autocomplete="inline":仅适用于搜索建议内联插入(如 GitHub @ 用户),会直接修改输入框 value,不适合表单字段——用户无法撤回或编辑插入部分
combobox 必须配齐 aria-expanded 和 aria-controls 才能被读屏识别
只写 role="combobox" 不够,屏幕阅读器需要明确知道“这个控件是否展开”以及“展开的内容在哪”。否则 NVDA/JAWS 可能完全忽略下拉行为,或误报为普通文本框。
- 触发元素(如
<input>)必须同时有:role="combobox"、aria-haspopup="listbox"、aria-expanded="false"、aria-controls="id-of-listbox" - 下拉容器(如
<ul>或<div>)必须设role="listbox",且 ID 与aria-controls值严格一致 -
aria-expanded必须由 JS 实时同步:点击展开时设为"true",收起时设为"false";不能靠 CSS visibility 或 display 控制
不要给 combobox 加 aria-activedescendant 除非你手动管理焦点
aria-activedescendant 的作用是让屏幕阅读器在不移动真实焦点的情况下,播报当前高亮项。但它不是“自动生效”的属性——你必须用 JS 主动更新它的值,并确保对应元素存在且是 role="option"。
- 如果你用
element.focus()把焦点真正在选项间切换,就不需要aria-activedescendant - 如果你用键盘导航但保持焦点始终在 input 上(模拟原生 select 行为),才需配合
aria-activedescendant+tabindex="-1"给每个选项 - 漏掉同步更新、指向不存在的 ID、或指向非
role="option"元素,会导致读屏静默或报错
combobox 不等于 autocomplete,别混用原生 autocomplete 属性
autocomplete="off" 或 autocomplete="name" 是 HTML 原生表单自动填充机制,和 ARIA 的 aria-autocomplete 完全无关。两者共存时,浏览器可能忽略 ARIA 语义,或导致输入框行为不可预测。
立即学习“前端免费学习笔记(深入)”;
- 自定义 combobox 中,应显式设
autocomplete="off"阻止浏览器自动填充干扰 -
aria-autocomplete只影响辅助技术对交互模式的理解,不影响浏览器 autofill 行为 - 若同时开启浏览器 autofill 和自定义下拉,用户可能看到两层建议(浏览器下拉 + 自定义 listbox),体验混乱
aria-expanded、aria-selected、焦点位置、键盘事件响应全部实时同步——差一步,视障用户就卡在“不知道菜单开了没”或者“按了方向键没反应”。



















