Normativas · ARIA

Rol Control

combobox

Marca una entrada de texto asociada a una lista emergente de valores — se usa para autocompletar, búsqueda por escritura anticipada y selectores personalizados. Recurra a role="combobox" solo cuando necesite filtrado, renderizado personalizado o sugerencias remotas; para selección simple use el <select> nativo.

Cuándo usar

Use <select> cuando la elección proviene de una lista corta y fija y el usuario no necesita filtrar. El elemento nativo incluye selectores adaptados a dispositivos móviles, soporte completo de teclado y sin necesidad de JavaScript.

role="combobox" es para los casos que el elemento nativo no puede cubrir:

  • Autocompletar con filtrado (búsqueda de ciudades, mención de usuarios).
  • Sugerencias obtenidas de una API remota.
  • Elementos renderizados con contenido enriquecido (avatares, texto secundario).
  • Entradas de etiquetas donde se pueden seleccionar múltiples valores.

ARIA 1.2 cambió significativamente el patrón combobox. El rol se coloca en el <input>, NO en el contenedor. La ventana emergente es un role="listbox" separado (o tree/grid/dialog) que el combobox posee a través de aria-controls.

Contrato de teclado y foco

Según el patrón combobox de la APG:

  • El foco permanece en el campo de entrada en todo momento. La lista desplegable se abre mediante aria-expanded="true" y la opción activa se rastrea con aria-activedescendant, SIN mover el foco.
  • La flecha hacia abajo abre la ventana emergente y mueve la opción activa al primer elemento.
  • Las flechas arriba/abajo mueven la opción activa dentro de la ventana emergente.
  • Enter selecciona la opción activa y cierra la ventana emergente.
  • Escape cierra la ventana emergente; con un segundo Escape, se borra el contenido del campo.
  • Escribir filtra la lista (cuando aria-autocomplete="list" o "both").

Establezca aria-autocomplete en "none", "inline", "list" o "both" para describir el comportamiento de sugerencias.

Errores frecuentes

  • Colocar role="combobox" en el contenedor en lugar del <input> (el patrón anterior a ARIA 1.2). Los lectores de pantalla modernos esperan el rol en el elemento editable.
  • Mover el foco del DOM hacia la lista desplegable al presionar la flecha hacia abajo. La APG exige aria-activedescendant; mover el foco interrumpe la escritura.
  • aria-expanded bloqueado en "false" incluso cuando la ventana emergente está visible.
  • Lista desplegable renderizada en el DOM pero nunca enlazada desde aria-controls.
  • Filtrar la lista dejando aria-activedescendant apuntando a un elemento que ya no existe.

Ejemplo

<label for="city">Ciudad</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">Londres</li>
  <li id="city-2" role="option">Lisboa</li>
  <li id="city-3" role="option">Liubliana</li>
</ul>