listbox
Marca un elemento como una lista de opciones seleccionables. Se recomienda usar <select> para el caso simple de selección única. Recurrir a role="listbox" cuando se necesite estilo personalizado, selección múltiple con renderizado propio o combinación con un combobox.
Cuándo utilizarlo
Se debe usar <select> (selección única) o <select multiple> siempre que sea posible. El elemento nativo proporciona el modelo de interacción completo, incluido el manejo de teclado correcto para cada plataforma.
role="listbox" es adecuado cuando:
- El listbox es el desplegable de un combobox personalizado.
- Se necesita contenido enriquecido en las opciones (iconos, texto secundario) que
<select>no puede renderizar. - Se requiere selección múltiple con estilo de marca de verificación personalizado.
- Se está construyendo un transfer list o un selector filtrable.
Los elementos hijo deben tener role="option" (con role="group" permitido como contenedor intermedio para la organización en secciones). Se debe establecer aria-multiselectable="true" en los listboxes de selección múltiple.
Contrato de teclado y foco
Según el patrón de listbox de la APG:
- Tab mueve el foco al listbox; Tab lo saca. Dentro del listbox, el foco permanece en el contenedor y la opción «activa» se rastrea mediante
aria-activedescendant. - Las flechas Arriba/Abajo mueven la opción activa.
- Inicio / Fin saltan a la primera / última opción.
- Selección única: cada pulsación de flecha también selecciona la opción activa.
- Selección múltiple: Espacio alterna la selección de la opción activa; Shift+Flecha extiende un rango contiguo; Ctrl/Cmd+A selecciona todo.
- Escritura anticipada: al escribir una letra, el cursor salta a la siguiente opción que comienza con esa letra.
Errores frecuentes
- Mover el foco del DOM a cada opción en lugar de usar
aria-activedescendant. Rompe la escritura anticipada y la integración con el combobox. - Elementos hijo
role="option"sin atributosid—aria-activedescendantno puede referenciarlos. - Listbox de selección múltiple sin
aria-multiselectable="true". Los lectores de pantalla lo anuncian como de selección única. - El listbox contiene opciones situadas en otra parte del DOM sin usar
aria-ownspara hacer explícita la relación. - Usar
role="listbox"para una lista estática de elementos de solo lectura. En ese caso corresponderole="list", no listbox — listbox implica interactividad.
Ejemplo
<label id="topicsLabel">Seleccione sus temas</label>
<ul
role="listbox"
aria-labelledby="topicsLabel"
aria-multiselectable="true"
tabindex="0"
aria-activedescendant="topic-1"
>
<li id="topic-1" role="option" aria-selected="true">Accesibilidad</li>
<li id="topic-2" role="option" aria-selected="false">Tecnología de apoyo</li>
<li id="topic-3" role="option" aria-selected="true">Estándares</li>
</ul>