combobox
Marque un champ texte associé à une liste contextuelle de valeurs — utilisé pour la saisie automatique, la recherche par anticipation et les selects personnalisés. Le natif <select> gère la sélection simple ; n'utilisez role="combobox" que pour le filtrage, le rendu personnalisé ou les suggestions distantes.
Quand l’utiliser
Utilisez <select> lorsque le choix provient d’une liste courte et fixe et que l’utilisateur n’a pas besoin de filtrer. L’élément natif offre des sélecteurs adaptés au mobile, un support clavier complet et aucun JavaScript.
role="combobox" est réservé aux cas que le natif ne peut pas couvrir :
- Saisie automatique avec filtrage (recherche de ville, mention d’utilisateur).
- Suggestions récupérées depuis une API distante.
- Éléments rendus avec du contenu enrichi (avatars, texte secondaire).
- Champs de tags où plusieurs valeurs peuvent être sélectionnées.
ARIA 1.2 a modifié significativement le motif combobox. Le rôle est placé sur le <input>, PAS sur le conteneur. La popup est un role="listbox" séparé (ou tree/grid/dialog) que le combobox possède via aria-controls.
Contrat clavier + focus
Conformément au motif APG combobox :
- Le focus reste sur le champ en permanence. La listbox est ouverte via
aria-expanded="true"et l’option active est suivie viaaria-activedescendant, PAS en déplaçant le focus. - La flèche bas ouvre la popup et déplace l’option active sur le premier élément.
- Les flèches haut/bas déplacent l’option active dans la popup.
- Entrée sélectionne l’option active et ferme la popup.
- Échap ferme la popup ; au second Échap, efface le champ.
- La frappe filtre la liste (quand
aria-autocomplete="list"ou"both").
Définissez aria-autocomplete à "none", "inline", "list" ou "both" pour décrire le comportement des suggestions.
Erreurs fréquentes
- Placer
role="combobox"sur le conteneur plutôt que sur le<input>(le motif pré-1.2). Les lecteurs d’écran modernes s’attendent à ce que le rôle soit sur l’élément éditable. - Déplacer le focus DOM dans la listbox sur flèche-bas. L’APG impose
aria-activedescendant; déplacer le focus interrompt la frappe. aria-expandedbloqué à"false"même quand la popup est visible.- Listbox rendue dans le DOM mais jamais liée depuis
aria-controls. - Filtrer la liste en laissant
aria-activedescendantpointer vers un élément qui n’existe plus.
Exemple
<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>