Standarder · ARIA

Rolle Widget

combobox

Markerer et tekstfelt parret med en popup-liste — bruges til autofuldførelse, type-ahead-søgning og brugerdefinerede valglister. Det native <select> håndterer enkeltvalg; brug kun role="combobox", når du har brug for filtrering, brugerdefineret rendering eller fjernforslag.

Hvornår skal det bruges

Brug <select>, når valget er fra en kort, fast liste, og brugeren ikke behøver at filtrere. Det native element kommer med mobilvenlige vælgere, fuld tastaturunderstøttelse og ingen JavaScript.

role="combobox" er til de tilfælde, det native element ikke kan nå:

  • Autofuldførelse med filtrering (bysøgning, brugermentioner).
  • Forslag hentet fra en ekstern API.
  • Elementer gengivet med rigt indhold (avatarer, sekundær tekst).
  • Tag-input, hvor flere værdier kan vælges.

ARIA 1.2 ændrede combobox-mønsteret væsentligt. Rollen placeres på <input>, IKKE på indpakningen. Popup’en er et separat role="listbox" (eller tree/grid/dialog), som combobox’en ejer via aria-controls.

Tastatur- og fokuskontrakt

Ifølge APG combobox-mønsteret:

  • Fokus forbliver på inputtet hele tiden. Listboxen åbnes via aria-expanded="true", og den aktive mulighed spores via aria-activedescendant — IKKE ved at flytte fokus.
  • Pil ned åbner popup’en og flytter den aktive mulighed til det første element.
  • Pil op/ned flytter den aktive mulighed inden for popup’en.
  • Enter vælger den aktive mulighed og lukker popup’en.
  • Escape lukker popup’en; ved et andet Escape ryddes inputtet.
  • Skrivning filtrerer listen (når aria-autocomplete="list" eller "both").

Sæt aria-autocomplete til "none", "inline", "list" eller "both" for at beskrive forslagsadfærden.

Hyppige fejl

  • Placering af role="combobox" på indpakningen i stedet for <input> (pre-1.2-mønsteret). Moderne skærmlæsere forventer rollen på det redigerbare element.
  • Flytning af DOM-fokus ind i listboxen ved pil ned. APG kræver aria-activedescendant; flytning af fokus bryder skrivning.
  • aria-expanded fastlåst til "false" selv når popup’en er synlig.
  • Listbox gengivet i DOM, men aldrig tilknyttet fra aria-controls.
  • Filtrering af listen, men aria-activedescendant peger stadig på et element, der ikke længere eksisterer.

Eksempel

<label for="city">By</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">Lissabon</li>
  <li id="city-3" role="option">Ljubljana</li>
</ul>