标准 · ARIA

角色 控件

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>