角色 控件
combobox
将文本输入框与弹出值列表配对标记——用于自动补全、即时搜索和自定义下拉选择。原生 <select> 元素可处理简单的单选场景;仅当需要筛选、自定义渲染或远程建议时才使用 role="combobox"。
使用时机
当选项来自简短固定列表且用户无需筛选时,使用 <select>。原生元素内置移动端友好的选择器、完整的键盘支持,无需任何 JavaScript。
以下情形原生元素无法胜任,应使用 role="combobox":
- 带筛选功能的自动补全(城市搜索、用户提及)。
- 从远程 API 获取建议项。
- 带富内容渲染的条目(头像、次要文本)。
- 可选择多个值的标签输入框。
ARIA 1.2 对 combobox 模式作出了重大调整。该角色应放置在 <input> 上,而非外层容器上。弹出层为独立的 role="listbox"(或 tree/grid/dialog),由 combobox 通过 aria-controls 关联。
键盘与焦点规范
根据 APG combobox 模式:
- 焦点始终保持在输入框上。列表框通过
aria-expanded="true"打开,当前激活选项通过aria-activedescendant跟踪,而不通过移动焦点实现。 - 向下箭头键打开弹出层,并将激活选项移至第一项。
- 上/下箭头键在弹出层内移动激活选项。
- Enter 键选中当前激活选项并关闭弹出层。
- Escape 键关闭弹出层;再次按下 Escape 则清空输入框。
- 输入字符时筛选列表(当
aria-autocomplete="list"或"both"时)。
将 aria-autocomplete 设置为 "none"、"inline"、"list" 或 "both",以描述建议行为。
常见错误
- 将
role="combobox"放在外层容器而非<input>上(这是 ARIA 1.2 之前的旧模式)。现代屏幕阅读器要求角色设置在可编辑元素上。 - 按下向下箭头键时将 DOM 焦点移入列表框。APG 规定必须使用
aria-activedescendant;移动焦点会破坏正常输入。 - 弹出层可见时
aria-expanded仍为"false"。 - 列表框已渲染至 DOM 但未通过
aria-controls关联。 - 筛选列表后
aria-activedescendant仍指向已不存在的条目。
示例
<label for="city">City</label>
<input
id="city"
type="text"
role="combobox"
aria-controls="cityList"
aria-expanded="false"
aria-autocomplete="list"
aria-activedescendant=""
>
<ul id="cityList" role="listbox" hidden>
<li id="city-1" role="option">London</li>
<li id="city-2" role="option">Lisbon</li>
<li id="city-3" role="option">Ljubljana</li>
</ul>