Combobox
Combobox lar brukeren søke etter og velge ett eller flere alternativer fra en liste. Brukeren skriver for å filtrere, og valgte alternativer vises enten som verdi i feltet (single) eller som chips over feltet (flervalg).
Combobox er en sammensatt komponent med en del markup. Combobox i ren HTML gir en full gjennomgang av anatomien, hvordan et valg fungerer, forhåndsvalg og form-innsending.
Egnet til
- Lange lister der brukeren raskt vil filtrere seg frem
- Valg der søk er raskere enn å skanne alle alternativer (f.eks. land, kommune)
- Flervalg der valgte alternativer bør vises tydelig som chips
- Situasjoner der brukeren kjenner navnet på det de leter etter
Uegnet til
- Korte lister med få alternativer (bruk RadioGroup eller Select)
- Når brukeren skal skrive inn en fri verdi som ikke finnes i lista
- Når alle alternativer alltid bør være synlige samtidig
Bruk
Prøv å skrive for å filtrere lista. Søket treffer både label, verdi og beskrivelse — så «+47» eller «47» finner Norge like godt som «Norge». Filtreringen er locale-bevisst (norsk collator, æ/ø/å-korrekt og aksent-uavhengig). noHitsText og toggleLabel er tekster du selv oversetter.
Eksempler
Forhåndsvalgte verdier
I React setter du startverdi med defaultValue (ukontrollert) eller value (kontrollert). I ren HTML markerer du alternativet med aria-selected="true" — se Combobox i ren HTML for detaljene.
I React setter du startverdi med defaultValue (ukontrollert) eller value (kontrollert) — '47' i single, ['47', '46'] i flervalg.
Kontrollert vs. ukontrollert (React)
I React kan feltet være ukontrollert eller kontrollert:
- Ukontrollert: sett
defaultValuefor startverdi. Komponenten eier verdien etter mount, og senere endringer avdefaultValueignoreres (som i vanlige React-inputs). - Kontrollert: sett
valueog oppdater den ionChange. Da er React sanningskilden.
Verditypen følger multiple: string i single, string[] i flervalg. I single får onChange en tom streng ('') når alt fjernes. onChange kalles ved valg, avmarkering og fjerning av chip.
Søk/filtrering skjer inne i web-komponenten (locale-bevisst, treffer label, verdi og beskrivelse) og kan ikke overstyres med en prop fra React. Ved 0 treff vises noHitsText i en role="status"-region.
Flervalg med chips
I flervalg holdes lista åpen etter valg, inputfeltet tømmes, og valgte alternativer vises som chips. Chips nås med piltast og fjernes med Backspace eller klikk.
Med hjelpetekst
Med feilmelding
Deaktivert
Retningslinjer
Bruk combobox når det er raskere å skrive enn å lete
Combobox lønner seg når listen er så lang at brukeren vet svaret før hen finner det: land, kommuner, kontoer, verdipapirer. Er det få nok alternativer å lese gjennom, gir Select eller RadioGroup mindre å forholde seg til.
La brukeren se hva som er valgt
I enkeltvalg står valgt verdi i feltet. I flervalg ligger valgene som chips over feltet, og i lista får de en hake. Haken er en form, ikke bare en farge, slik at valget også er synlig for den som ikke skiller fargene.
Fri tekst hører ikke her
Brukeren kan bare velge blant alternativene i lista. Skal verdien kunne være noe annet enn det du har definert, bruk et vanlig tekstfelt.
Sorter alternativene forutsigbart
Alfabetisk er utgangspunktet. I lange lister kan de mest brukte alternativene ligge øverst, så treffer brukeren dem uten å skrive noe.
Universell utforming
Semantisk struktur og korrekt rolle
Combobox følger ARIA Authoring Practices sitt combobox-mønster: inputfeltet får role="combobox" med aria-autocomplete="list", aria-expanded og aria-controls. Lista er role="listbox" og alternativene role="option". I single settes aria-selected="true" kun på det valgte alternativet (de øvrige har ingen aria-selected, så skjermleseren slipper å lese «ikke valgt» for hvert). I flervalg vises valgte verdier som chips med role="button" i en role="group"-wrapper (chipsLabel) — ikke som option-er utenfor en listbox.
Virtual focus
DOM-fokus blir alltid på inputfeltet. Aktivt alternativ spores med aria-activedescendant, slik at brukeren kan skrive og pil-navigere samtidig uten at fokus flyttes fysisk inn i lista.
Tydelig fokus og tastaturnavigasjon
Combobox er fullt opererbar med tastatur. Feltet nås med Tab, lista åpnes ved skriving eller piltast, alternativer velges med Enter og lista lukkes med Escape. I flervalg nås chips med piltast og fjernes med Backspace.
Tilstrekkelig størrelse og klikkeflate
Toggle-knappen og alternativene oppfyller minimum 44×44 px klikkflate.
i18n — send inn oversatt tekst
Komponenten har ingen innebygde tekster. noHitsText, toggleLabel, removeChipLabel, chipsLabel, arrowHintText og resultsText må sendes inn på riktig språk (bokmål, nynorsk, engelsk). Det finnes ingen norsk fallback — det ville smittet over på andre språk.
I utviklingsbygg (import.meta.env.DEV) varsler web-komponenten med console.warn når en påkrevd tekst mangler: toggle-knappen uten aria-label (React: toggleLabel), flervalg uten data-remove-chip-label (React: removeChipLabel) eller uten data-chips-label (React: chipsLabel), eller input uten tilgjengelig navn. resultsText er en forbedring — mangler den, annonseres antall treff ikke (ingen advarsel). Advarslene fjernes fra produksjonsbygg.
Tastaturnavigasjon
| Tast | Handling |
|---|---|
| Tab | Flytter fokus til inputfeltet |
| Shift+Tab | Flytter fokus til forrige fokuserbare element |
| Bokstav | Filtrerer lista og åpner den |
| Arrow Down | Åpner lista / flytter aktivt alternativ nedover |
| Arrow Up | Flytter aktivt alternativ oppover |
| Enter | Velger aktivt alternativ (lukker lista i single, holder åpen i multi) |
| Escape | Lukker lista uten å endre valg |
| Backspace | Tom input i multi: flytter fokus til siste chip. På chip: fjerner chipen |
| Arrow Left/Right | Flervalg: navigerer mellom valgte chips |
Skjermleser
- Ved fokus: "[label], kombinasjonsboks, sammenrullet"
- Ved skriving: aktivt alternativ annonseres via aria-activedescendant: "[alternativ], [posisjon] av [total]" (single leser "valgt" kun på det valgte, ikke "ikke valgt" på hvert)
- Ved filtrering: antall treff annonseres via en skjult role=status (resultsText), f.eks. "5 alternativer"
- Flervalg: "[label], kombinasjonsboks" + skjult aria-describedby-hint som forklarer chip-navigasjon
- Ved 0 treff: no-hits-teksten annonseres via role=status
- Valgt chip: "[alternativ], [fjern-tekst], knapp" i gruppen [chipsLabel]
- Ved feil: "[label], ugyldig, kombinasjonsboks, [feilmelding]"
WCAG-kriterier
Sist gjennomgått: 2026-07-13 — alle 56 WCAG 2.2-kriterier vurdert
WCAG-kriterier8 ditt ansvar · 18 håndtert · 30 ikke relevant · 0 ikke på plass
Ditt ansvar (8)
| Kriterium | Nivå | Hva du må gjøre |
|---|---|---|
| 2.4.6 Overskrifter og ledetekster | AA | Skriv beskrivende labeltekst. Labelen skal forklare hva brukeren skal velge — ikke handlingen. "Land" er bedre enn "Søk og velg land". Alle combobox-felter må ha en label, enten synlig eller via ariaLabel. |
| 3.3.2 Ledetekster eller instruksjoner | A | Skriv beskrivende labeltekst. Labelen skal forklare hva brukeren skal velge — ikke handlingen. "Land" er bedre enn "Søk og velg land". Alle combobox-felter må ha en label, enten synlig eller via ariaLabel. |
| 3.1.1 Språk på siden | A | Send inn oversatt tekst for alle strenger. noHitsText, toggleLabel, removeChipLabel, chipsLabel, arrowHintText og resultsText leses av skjermleser og/eller vises i UI. Komponenten har ingen innebygde fallback-tekster — send inn riktig streng for språket ditt (bokmål, nynorsk, engelsk). resultsText er en mal med {n} som byttes med antall treff. |
| 3.1.2 Språk på deler av innhold | AA | Send inn oversatt tekst for alle strenger. noHitsText, toggleLabel, removeChipLabel, chipsLabel, arrowHintText og resultsText leses av skjermleser og/eller vises i UI. Komponenten har ingen innebygde fallback-tekster — send inn riktig streng for språket ditt (bokmål, nynorsk, engelsk). resultsText er en mal med {n} som byttes med antall treff. |
| 3.3.1 Identifikasjon av feil | A | Skriv gode feilmeldinger. Feilmeldingen må si hva som er galt og hva brukeren skal gjøre. "Du må velge et land" — ikke "Ugyldig valg". Komponenten viser og annonserer meldingen, men du skriver innholdet. |
| 3.3.3 Forslag ved feil | AA | Skriv gode feilmeldinger. Feilmeldingen må si hva som er galt og hva brukeren skal gjøre. "Du må velge et land" — ikke "Ugyldig valg". Komponenten viser og annonserer meldingen, men du skriver innholdet. |
| 2.4.6 Overskrifter og ledetekster | AA | Bruk meningsfulle option-tekster. Hvert alternativ skal ha en tydelig og beskrivende label. Beskrivelsen (andrelinje) er valgfri tilleggsinfo, ikke en erstatning for en klar label. "Norge" er bedre enn "NO". |
| 3.3.2 Ledetekster eller instruksjoner | A | Ved flervalg: forklar chip-navigasjonen. arrowHintText kobles via aria-describedby (skjult element) på inputfeltet og forteller skjermleserbrukere at valgte alternativer (chips) nås med piltast. chipsLabel gir chip-gruppen (role=group) et tilgjengelig navn. Send inn begge i multi-modus. |
Håndtert av komponenten (18)
| Kriterium | Nivå | Hva komponenten gjør |
|---|---|---|
| 1.3.1 Informasjon og relasjoner | A | input får role=combobox med aria-autocomplete=list, aria-expanded og aria-controls til listbox. Lista er role=listbox, alternativer role=option. Single: aria-selected=true kun på valgt (øvrige uten attributt, APG). Multi: valgte vises som chips med role=button i en role=group-wrapper (chipsLabel). Skjult select gir semantisk form-verdi. |
| 1.3.2 Meningsfull rekkefølge | A | Chips, felt, liste og feilmelding følger naturlig rekkefølge i DOM. |
| 1.3.3 Sensoriske egenskaper | A | Valgt tilstand vises med checkmark (struktur) i tillegg til bakgrunn — i både single og flervalg, ikke farge alene. |
| 1.4.1 Bruk av farge | A | Valgt og aktivt alternativ kommuniseres med checkmark (begge moduser) og bakgrunn, ikke farge alene. Feiltilstand bruker tekst, ramme og aria-invalid. |
| 1.4.4 Endre tekststørrelse | AA | Relative enheter — skalerer korrekt ved 200 % zoom. |
| 1.4.10 Omflyt | AA | Reflower korrekt ned til 320px viewport. Chips brytes over flere linjer. |
| 1.4.11 Kontrast for ikke-tekstlig innhold | AA | Ramme, fokusindikator og aktivt alternativ oppfyller 3:1 kontrastkrav. |
| 1.4.12 Tekstavstand | AA | Tåler økt line-height, bokstav- og ordavstand uten tap av innhold. |
| 1.4.13 Innhold ved hover eller fokus | AA | Lista lukkes forutsigbart med Escape og klikk utenfor; ingen hover-only innhold som forsvinner utilsiktet. |
| 2.1.1 Tastatur | A | Fullt opererbart med tastatur: piltaster navigerer i lista (virtual focus via aria-activedescendant), Enter velger, Escape lukker, Backspace fjerner chip, piltast navigerer mellom chips. |
| 2.1.2 Ingen tastaturfelle | A | Fokus blir på inputfeltet og kan navigeres ut med Tab/Shift+Tab. Ingen tastaturfelle. |
| 2.4.3 Fokusrekkefølge | A | Ett tab-stopp på feltet; chips nås med piltast (radiogruppe-modell), ikke egne tab-stopp. Naturlig DOM-rekkefølge. |
| 2.4.7 Synlig fokus | AA | Tydelig fokusindikator på inputfeltet og på toggle-knappen ved tastaturfokus. |
| 2.5.8 Målstørrelse (minimum) | AA | Toggle-knapp og alternativer oppfyller minimum 44x44px klikkflate. |
| 3.2.1 Ved fokus | A | Fokus alene trigger ingen kontekstendring — lista åpnes ved skriving, klikk eller piltast, ikke ved fokus. |
| 3.2.2 Ved inndata | A | Valg trigger ingen automatisk kontekstendring med mindre onChange eksplisitt gjør det. |
| 4.1.2 Navn, rolle, verdi | A | APG combobox-mønster: role=combobox/listbox/option, aria-expanded, aria-controls, aria-activedescendant, aria-selected, aria-multiselectable. Chips er role=button i en role=group-wrapper (gyldig navn/rolle, ikke orphan options). Piltast-hint kobles via aria-describedby (skjult element), additivt sammen med ix-field sin describedby. Tilgjengelig navn fra label. |
| 4.1.3 Statusmeldinger | AA | To role=status live-regioner: synlig no-hits-melding ved 0 treff, og en skjult (sr-only) region som annonserer antall treff (resultsText, {n}) ved filtrering — debounced og kun når antallet endres, så skjermleseren ikke oversvømmes. Feilmelding annonseres via ix-field sin aria-live=polite. |
Ikke relevant (30)
| Kriterium | Nivå | Hvorfor ikke relevant |
|---|---|---|
| 1.1.1 Ikke-tekstlig innhold | A | Checkmark og chevron er dekorative CSS-masker med aria-hidden; ingen informasjonsbærende bilder. |
| 1.2.1 Bare lyd og bare video (forhåndsinnspilt) | A | Ingen medieelementer. |
| 1.2.2 Teksting (forhåndsinnspilt) | A | Ingen medieelementer. |
| 1.2.3 Synstolking eller mediealternativ (forhåndsinnspilt) | A | Ingen medieelementer. |
| 1.2.4 Teksting (direkte) | AA | Ingen medieelementer. |
| 1.2.5 Synstolking (forhåndsinnspilt) | AA | Ingen medieelementer. |
| 1.3.4 Visningsretning | AA | Ingen fast orientering — tilpasser seg visningsretning. |
| 1.3.5 Identifiser formål med inndata | AA | Ikke et felt for personlig informasjon — autocomplete gjelder ikke. |
| 1.4.2 Styring av lyd | A | Ingen lydelementer. |
| 1.4.5 Bilder av tekst | AA | Ingen bilder av tekst. |
| 2.1.4 Tastatursnarveier | A | Ingen egendefinerte tastatursnarveier. |
| 2.2.1 Justerbar hastighet | A | Ingen tidsbegrensede funksjoner. |
| 2.2.2 Pause, stopp, skjul | A | Ingen animasjon eller automatisk oppdatering. |
| 2.3.1 Terskelverdi på tre glimt | A | Ingen blinkende eller glimtende innhold. |
| 2.4.1 Hoppe over blokker | A | Sidekrav — gjelder ikke enkeltkomponenter. |
| 2.4.2 Sidetitler | A | Sidekrav — gjelder ikke enkeltkomponenter. |
| 2.4.4 Formål med lenke (i kontekst) | A | Ingen lenker i komponenten. |
| 2.4.5 Flere måter | AA | Sidekrav — gjelder ikke enkeltkomponenter. |
| 2.4.11 Fokus ikke skjult (minimum) | AA | Ingen sticky/overlappende elementer som kan skjule fokus. |
| 2.5.1 Pekerbevegelser | A | Ingen bevegelsesbaserte gester — alt betjenes med enkle trykk/klikk. |
| 2.5.2 Avbryt peker | A | |
| 2.5.4 Bevegelsesaktivering | A | Ingen bevegelsesaktivering. |
| 2.5.6 Samtidige inndatamekanismer | A | |
| 2.5.7 Drabevegelser | A | Ingen drag-and-drop. |
| 3.2.3 Konsistent navigasjon | AA | Sidekrav — gjelder ikke enkeltkomponenter. |
| 3.2.4 Konsistent identifikasjon | AA | Systemkrav — gjelder konsistens på tvers av sider, ikke enkeltkomponenter. |
| 3.2.6 Konsistent hjelp | A | Sidekrav — gjelder plassering av hjelpefunksjon på tvers av sider. |
| 3.3.4 Forhindring av feil (juridisk, økonomisk, data) | AA | Flytkrav — gjelder bekreftelse/reversering av transaksjoner, ikke enkeltfelter. |
| 3.3.7 Redundant oppføring | A | Flytkrav — gjelder at brukeren ikke skal gjenta informasjon i en prosess. |
| 3.3.8 Tilgjengelig autentisering (minimum) | AA | Ikke en autentiseringskomponent. |
Props / API
ComboboxProps
| Prop | Type | Påkrevd | Standard | Beskrivelse |
|---|---|---|---|---|
label | string | Nei* | Synlig labeltekst. Anbefalt fremfor ariaLabel | |
ariaLabel | string | Nei* | Skjult label for skjermlesere. *Enten label eller ariaLabel må settes | |
options | ComboboxOption[] | Ja | Alternativene i lista | |
noHitsText | string | Ja | Tekst i lista når filteret gir 0 treff (i18n) | |
multiple | boolean | Nei | false | Flervalg med chips |
value | string | string[] | Nei | Kontrollert verdi. string i single, string[] i multi | |
defaultValue | string | string[] | Nei | Ukontrollert startverdi. Virker kun ved mount | |
onChange | (value: string | string[]) => void | Nei | Kalles ved valg/avmarkering/fjerning. Får string i single ('' når tomt), string[] i multi | |
placeholder | string | Nei | Frarådes: placeholder forsvinner når brukeren skriver. Bruk description til hint | |
description | string | Nei | Hjelpetekst under label | |
errorMessage | string | Nei | Feilmelding. Trigger aria-invalid når den har innhold | |
disabled | boolean | Nei | Deaktiverer feltet | |
readOnly | boolean | Nei | Skrivebeskyttet felt | |
required | boolean | Nei | Markerer feltet som påkrevd | |
toggleLabel | string | Nei | aria-label på chevron-knappen (i18n) | |
removeChipLabel | string | Nei | Suffiks på chip-ens aria-label, f.eks. "fjern" (i18n, multi) | |
chipsLabel | string | Nei | aria-label på chip-gruppen (role="group"), f.eks. "Valgte alternativer" (i18n, multi) | |
arrowHintText | string | Nei | Skjult hint (aria-describedby) som forklarer chip-navigasjon (i18n, multi) | |
resultsText | string | Nei | Mal for skjermleser-annonsering av antall treff. {n} byttes med antallet, f.eks. "{n} alternativer" (i18n) | |
name | string | Nei | Navn på skjult <select> for form-innsending | |
className | string | Nei | CSS-klasse på ytterste wrapper (.ix-field) | |
ref | Ref<IxCombobox> | Nei | Ref videresendes til <ix-combobox>-elementet |
ComboboxOption
| Prop | Type | Påkrevd | Beskrivelse |
|---|---|---|---|
value | string | Ja | Verdien som sendes ved valg |
label | string | Ja | Teksten som vises for alternativet |
description | string | Nei | Valgfri andrelinje under label |
disabled | boolean | Nei | Gjør alternativet utilgjengelig for valg |
Tilpasning med CSS
Tilgjengelige klasser og selektorer
| Element | Selektor |
|---|---|
| Rot | .ix-combobox |
| Chips-wrapper | .ix-combobox__chips |
| Toggle-knapp | .ix-combobox__toggle |
| Listbox | .ix-combobox__listbox |
| Alternativ | .ix-combobox__option |
| Checkmark | .ix-combobox__option-check |
| Ingen treff | .ix-combobox__no-hits |
Relatert
- Combobox i ren HTML — full gjennomgang av HTML-markup, forhåndsvalg og form-innsending
- Select — for enkelt valg fra kort/mellomlang liste uten søk
- Label — labeltekst for feltet
- Chip — chip-stilen som gjenbrukes for valgte alternativer i flervalg