DropdownMenu
DropdownMenu er en nedtrekksmeny for handlinger eller navigasjon. Menyen vises når brukeren interagerer med en trigger-knapp og lukkes automatisk ved valg, klikk utenfor eller Escape.
Egnet til
- Handlinger knyttet til et objekt (rediger, dupliser, slett)
- Sekundære valg som ikke trenger synlige knapper
- Kontekstmenyer med flere relaterte handlinger
- Hierarkisk organisering av valg via submenyer
Uegnet til
- Primærhandlinger som bør være umiddelbart synlige (bruk Button)
- Valg i skjemaer (bruk Select eller RadioGroup)
- Navigasjon mellom seksjoner (bruk Tabs eller vanlige lenker)
- Svært lange lister (vurder Combobox med søk)
Bruk
En DropdownMenu bygges opp av en trigger-knapp og et menypanel med elementer. Klikk eller tastaturnavigasjon (Enter/Space/piler) åpner menyen og aktiverer valg. Menyen lukkes ved valg, klikk utenfor eller Escape.
React-komponenten er bygget opp som compound components: DropdownMenu.Trigger, DropdownMenu.Content, DropdownMenu.Item, DropdownMenu.Divider og sub-komponenter for nøstede menyer.
Eksempler
Med ikoner
Ikoner kan legges til foran teksten for å gjøre handlinger lettere å skanne.
Med destruktive handlinger
Bruk data-danger (HTML) eller danger-prop (React) for destruktive handlinger. Elementet får rød tekstfarge som visuell indikasjon.
Med gruppering
Bruk dividers for å visuelt skille grupper av relaterte handlinger.
Med submeny
For hierarkiske valg kan du nøste en submeny. Submenyen åpnes med ArrowRight og lukkes med ArrowLeft. Begrens til ett nivå med nøsting for god brukervennlighet.
Med deaktiverte elementer
Bruk disabled for elementer som ikke kan velges i nåværende tilstand. Deaktiverte elementer hoppes over ved tastaturnavigasjon.
Retningslinjer
Start hvert punkt med et verb
«Rediger», «Slett», «Eksporter som PDF». Punktet skal si hva som skjer når brukeren velger det. «Mer» og «Handlinger» hører på knappen som åpner menyen, ikke inni den.
Grupper relaterte handlinger
Skill grupper som hører sammen med en divider, så kan menyen skannes i bolker istedenfor linje for linje. Destruktive handlinger som slett og fjern hører nederst, bak sin egen divider, der de ikke treffes ved et uhell.
Begrens antall valg
Over 7–10 punkter blir menyen en liste å lete i. Da er det bedre å gruppere, flytte noe til en submeny, eller ta et steg tilbake og se på flyten.
Unngå dyp nøsting
Ett nivå submeny er nok. Dypere må brukeren huske hvor hen er samtidig som hen navigerer, og med tastatur er det tungt: hvert nivå må åpnes og lukkes med piltaster.
Universell utforming
Hva du selv må sørge for
- Bruk en tydelig trigger-knapp. Teksten eller
aria-labelskal fortelle hva menyen inneholder. Komponenten setteraria-haspopupogaria-expandedautomatisk. - Skriv korte og beskrivende meny-etiketter. Hvert element bør ha presis tekst som beskriver handlingen. Unngå vage etiketter.
- Oversett all tekst: trigger-tekst og meny-etiketter kommer fra deg og må være på brukerens språk.
- Begrens nesting. Dyp nøsting gjør navigasjon vanskelig. Hold deg til maksimalt ett nivå med submenyer.
- Unngå for mange valg. En lang meny er vanskelig å navigere. Grupper med dividers eller redesign flyten.
Hva komponenten gjør automatisk
- ARIA-attributter:
aria-haspopup="menu"ogaria-expandedsettes på trigger.role="menu"på menyen,role="menuitem"på elementer,role="separator"på dividers. - Tastaturnavigasjon: Enter/Space åpner, piltaster navigerer, Escape lukker. Home/End hopper til første/siste. ArrowRight åpner submeny, ArrowLeft lukker den.
- Fokushåndtering: fokus flyttes til første element ved åpning og tilbake til trigger ved lukking. Roving tabindex gjør at kun ett element har tabindex="0".
- Typeahead: skriv bokstaver for å hoppe til matchende element.
- Posisjonering: menyen plasseres med viewport-clamp og flipper ved plassmangel.
- Touch-mål: alle elementer har minimum 32px høyde.
- Fokusindikator: tydelig
:focus-visiblepå alle interaktive elementer.
Tastaturnavigasjon
| Tast | Handling |
|---|---|
| Enter / Space | Apner menyen nar trigger har fokus. Aktiverer valgt menyelement nar menyen er apen |
| ArrowDown | Apner menyen fra trigger. I apen meny: flytter fokus til neste element (hopper over disabled) |
| ArrowUp | Apner menyen fra trigger. I apen meny: flytter fokus til forrige element (hopper over disabled) |
| ArrowRight | Apner submeny nar fokus er pa submenu-trigger |
| ArrowLeft | Lukker submeny og returnerer fokus til forelder-trigger |
| Home | Flytter fokus til første menyelement |
| End | Flytter fokus til siste menyelement |
| Escape | Lukker menyen og returnerer fokus til trigger |
| Tab | Lukker menyen og flytter fokus til neste fokuserbare element pa siden |
| Bokstaver (a-z) | Typeahead: hopper til første element som starter med tastetrykket |
Skjermleser
- Ved fokus pa trigger: "[tekst], menyknapp, sammenslatt" eller "[tekst], menyknapp, utvidet" (avhengig av tilstand)
- Ved apning annonseres menyen med rolle, f.eks. "meny"
- Ved navigasjon: "[elementtekst], menyelement, [posisjon] av [total]"
- Ved disabled element: "[elementtekst], menyelement, deaktivert"
- Ved submenu-trigger: "[tekst], menyelement, undermeny"
- Ved lukking returneres fokus til trigger og den annonseres pa nytt
WCAG-kriterier
Sist gjennomgått: 2026-07-28 — alle 56 WCAG 2.2-kriterier vurdert
WCAG-kriterier8 ditt ansvar · 16 håndtert · 34 ikke relevant · 0 ikke på plass
Ditt ansvar (8)
| Kriterium | Nivå | Hva du må gjøre |
|---|---|---|
| 4.1.2 Navn, rolle, verdi | A | Bruk en tydelig trigger-knapp. Triggerknappen skal ha meningsfull tekst eller et tilgjengelig navn (aria-label) som forteller hva menyen inneholder. Brukeren skal forstå hva de kan forvente i menyen basert på triggeren. Komponenten setter automatisk aria-haspopup="menu" og aria-expanded på triggeren. |
| 2.4.6 Overskrifter og ledetekster | AA | Bruk en tydelig trigger-knapp. Triggerknappen skal ha meningsfull tekst eller et tilgjengelig navn (aria-label) som forteller hva menyen inneholder. Brukeren skal forstå hva de kan forvente i menyen basert på triggeren. Komponenten setter automatisk aria-haspopup="menu" og aria-expanded på triggeren. |
| 2.4.6 Overskrifter og ledetekster | AA | Skriv korte og beskrivende meny-etiketter. Hvert meny-element bør ha en kort og presis tekst som beskriver handlingen eller valget. Unngå vage etiketter som "Klikk her" eller "Mer". For destruktive handlinger, bruk danger-prop og tydelig tekst som "Slett" eller "Fjern". |
| 3.3.2 Ledetekster eller instruksjoner | A | Skriv korte og beskrivende meny-etiketter. Hvert meny-element bør ha en kort og presis tekst som beskriver handlingen eller valget. Unngå vage etiketter som "Klikk her" eller "Mer". For destruktive handlinger, bruk danger-prop og tydelig tekst som "Slett" eller "Fjern". |
| 3.1.2 Språk på deler av innhold | AA | Oversett all tekst i menyen. All tekst i trigger-knappen og meny-elementene kommer fra deg og skal være på brukerens språk (bokmål, nynorsk, engelsk). Komponenten har ingen hardkodet fallback-tekst. |
| 2.4.3 Fokusrekkefølge | A | Begrens nesting til ett niva. Submenyer kan brukes for a organisere valg hierarkisk, men dyp nesting (submeny i submeny i submeny) gjor navigasjon vanskelig, saerlig med tastatur og skjermleser. Begrens til maksimalt ett niva med submenyer der det er praktisk mulig. |
| 2.4.8 2.4.8 | ? | Begrens nesting til ett niva. Submenyer kan brukes for a organisere valg hierarkisk, men dyp nesting (submeny i submeny i submeny) gjor navigasjon vanskelig, saerlig med tastatur og skjermleser. Begrens til maksimalt ett niva med submenyer der det er praktisk mulig. |
| 3.2.3 Konsistent navigasjon | AA | Unnga for mange valg. En lang meny med mange valg er vanskelig a navigere. Vurder a gruppere med dividers, bruke submenyer for relaterte valg, eller redesigne flyten dersom menyen blir for lang (mer enn 7-10 elementer). |
Håndtert av komponenten (16)
| Kriterium | Nivå | Hva komponenten gjør |
|---|---|---|
| 1.3.1 Informasjon og relasjoner | A | Menyen har role="menu", hvert element har role="menuitem", og separatorer har role="separator". aria-haspopup="menu" og aria-expanded settes automatisk pa triggeren. Submenyer har aria-haspopup pa sin trigger. |
| 1.3.2 Meningsfull rekkefølge | A | Menyelementene vises i DOM-rekkefølge, og tastaturnavigasjon folger samme rekkefølge. Submenyer apnes til hoyre (eller venstre ved plassmangel) i leserekkefølge. |
| 1.4.3 Kontrast (minimum) | AA | Tekst bruker --ix-color-foreground-main-default pa --ix-color-surface-main-default. Danger-variant bruker --ix-color-foreground-danger-default som oppfyller kontrastkravet. |
| 1.4.4 Endre tekststørrelse | AA | Relative enheter (font-size-tokens) — tekst skalerer korrekt ved 200% zoom. Menyen har max-height og scroller ved behov. |
| 1.4.10 Omflyt | AA | Mobile-first uten faste bredder — menyen posisjoneres med viewport-clamp og flipper til andre siden ved plassmangel. Fungerer pa 320px viewport uten horisontal scroll. |
| 1.4.11 Kontrast for ikke-tekstlig innhold | AA | Fokusindikator pa menyelementer oppfyller 3:1 kontrastkrav via data-active. Hover-tilstand har subtil bakgrunnsendring som ikke er informasjonsbaerende. |
| 1.4.13 Innhold ved hover eller fokus | AA | Menyen forblir synlig til brukeren aktivt lukker den (klikk, Escape, Tab ut, eller valg). Ingen innhold forsvinner utilsiktet. |
| 2.1.1 Tastatur | A | Fullt tastaturopererbar: Enter/Space apner menyen, piltaster navigerer, Enter/Space velger, Escape lukker. Ingen museavhengige interaksjoner. |
| 2.1.2 Ingen tastaturfelle | A | Ingen tastaturfelle. Fokus holdes i menyen mens den er apen, men Escape lukker og Tab flytter fokus ut av menyen. ArrowLeft lukker submenyer og returnerer fokus til forelder-trigger. |
| 2.4.3 Fokusrekkefølge | A | Fokus flyttes til første menyelement ved apning. Ved lukking returneres fokus til triggeren. Tab-rekkefølge folger DOM inne i menyen. Roving tabindex gjor at kun ett element har tabindex="0" om gangen. |
| 2.4.7 Synlig fokus | AA | Tydelig fokusindikator pa alle menyelementer via data-active. Fokus er visuelt distinkt fra hover-tilstand. |
| 2.4.11 Fokus ikke skjult (minimum) | AA | Menyen har z-index-overlay og posisjoneres med getBoundingClientRect slik at den aldri dekkes av annet innhold. Fokuserte elementer i menyen er alltid synlige. |
| 2.5.8 Målstørrelse (minimum) | AA | Alle menyelementer har minimum 32px høyde for touch-mal (WCAG 2.5.8 AA). Full bredde gjor hele elementet klikkbart. |
| 3.2.1 Ved fokus | A | Ingen kontekstendring ved fokus. A navigere mellom menyelementer trigger ingen handling — kun aktivering (Enter/Space/klikk) gjor det. |
| 3.2.2 Ved inndata | A | Ingen uventet kontekstendring ved input. Menyen lukkes og handlingen utføres ved eksplisitt aktivering, ikke ved navigasjon. |
| 4.1.2 Navn, rolle, verdi | A | Trigger har aria-haspopup="menu", aria-expanded og aria-controls. Menu har role="menu". Items har role="menuitem" med disabled-state via aria-disabled. Submenytriggere har aria-haspopup="menu" og aria-expanded. |
Ikke relevant (34)
| Kriterium | Nivå | Hvorfor ikke relevant |
|---|---|---|
| 1.1.1 Ikke-tekstlig innhold | A | Ikoner i menyelementer er dekorative (aria-hidden) og supplementerer teksten. Chevron pa submenu-trigger er rent visuelt (teksten indikerer at det er en submeny). |
| 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.3 Sensoriske egenskaper | A | Formidler ikke instruksjoner basert pa sensoriske egenskaper. |
| 1.3.4 Visningsretning | AA | Menyen laser ikke visningsretning. |
| 1.3.5 Identifiser formål med inndata | AA | Komponenten er ikke et inndatafelt. |
| 1.4.1 Bruk av farge | A | Formidler ikke informasjon med farge alene. Danger-elementer har ogsa tydelig tekstinnhold. |
| 1.4.2 Styring av lyd | A | Ingen lydelementer. |
| 1.4.5 Bilder av tekst | AA | Ingen bilder av tekst. |
| 1.4.12 Tekstavstand | AA | |
| 2.1.4 Tastatursnarveier | A | Ingen enkelttegn-snarveier. Typeahead bruker flere tegn. |
| 2.2.1 Justerbar hastighet | A | Ingen tidsbegrensning pa menyen. |
| 2.2.2 Pause, stopp, skjul | A | Ingen automatisk oppdaterende eller blinkende innhold. |
| 2.3.1 Terskelverdi på tre glimt | A | Ingen animasjoner som blinker. |
| 2.4.1 Hoppe over blokker | A | Bypass blocks gjelder gjentakende sideblokker, ikke en enkelt meny. |
| 2.4.2 Sidetitler | A | Dokumenttittel er sidens ansvar, ikke komponentens. |
| 2.4.4 Formål med lenke (i kontekst) | A | |
| 2.4.5 Flere måter | AA | Sidekrav — gjelder ikke enkeltkomponenter. |
| 2.5.1 Pekerbevegelser | A | Ingen gestbaserte interaksjoner — enkelt klikk/tap. |
| 2.5.2 Avbryt peker | A | Native knapper — nettleseren handterer pekerinteraksjon. |
| 2.5.4 Bevegelsesaktivering | A | Ingen bevegelsesaktivering. |
| 2.5.7 Drabevegelser | A | Ingen dra-baserte interaksjoner. |
| 3.1.1 Språk på siden | A | Sidens sprak er sidens ansvar. |
| 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 | Ingen konsekvent hjelp-mekanisme i komponenten. |
| 3.3.1 Identifikasjon av feil | A | Komponenten har ingen validering. |
| 3.3.2 Ledetekster eller instruksjoner | A | Komponenten er ikke et skjemafelt. |
| 3.3.3 Forslag ved feil | AA | |
| 3.3.7 Redundant oppføring | A | Ingen gjentatt inntasting. |
| 3.3.8 Tilgjengelig autentisering (minimum) | AA | Ingen autentisering. |
Props / API
DropdownMenu
| Prop | Type | Standard | Beskrivelse |
|---|---|---|---|
open | boolean | Kontrollert åpen-tilstand. Utelat for ukontrollert bruk | |
defaultOpen | boolean | false | Startverdi i ukontrollert modus |
onOpenChange | (open: boolean) => void | Kalles når menyen åpnes eller lukkes | |
placement | 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end' | 'bottom-start' | Posisjon relativt til trigger |
children | ReactNode | Typisk DropdownMenu.Trigger og DropdownMenu.Content | |
className | string | Ekstra CSS-klasser på <ix-dropdown> |
DropdownMenu.Item
| Prop | Type | Standard | Beskrivelse |
|---|---|---|---|
onSelect | () => void | Kalles når elementet velges | |
danger | boolean | false | Destruktiv handling (rød tekst) |
disabled | boolean | false | Deaktiverer elementet |
icon | ReactNode | Ikon foran teksten | |
children | ReactNode | Tekst/innhold i elementet |
DropdownMenu.Divider
Ingen props. Rendrer en visuell separator med role="separator".
DropdownMenu.Sub, DropdownMenu.SubTrigger, DropdownMenu.SubContent
Disse komponentene bygger opp nøstede submenyer. Sub wrapper SubTrigger og SubContent. SubTrigger viser chevron-ikonet automatisk.
Tilpasning med CSS
Trenger du ix-dropdown-stylingen på HTML du setter sammen selv kan du bruke klassene direkte. Web componenten <ix-dropdown> håndterer ARIA og tastaturnavigasjon.
Tilgjengelige klasser og selektorer
| Element | Selektor |
|---|---|
| Host/wrapper | ix-dropdown eller .ix-dropdown |
| Meny-panel | .ix-dropdown__menu |
| Meny-element | .ix-dropdown__item |
| Separator | .ix-dropdown__divider |
| Submeny-trigger | .ix-dropdown__submenu-trigger |
| Chevron-ikon | .ix-dropdown__chevron |
| Danger-variant | [data-danger] på .ix-dropdown__item |
| Disabled | [disabled] eller [aria-disabled="true"] på .ix-dropdown__item |
Eksempel: ren HTML
<ix-dropdown>
<button class="ix-button" data-variant="secondary">Handlinger</button>
<div class="ix-dropdown__menu" role="menu">
<button class="ix-dropdown__item" role="menuitem">Rediger</button>
<button class="ix-dropdown__item" role="menuitem">Dupliser</button>
<hr class="ix-dropdown__divider" role="separator" />
<button class="ix-dropdown__item" role="menuitem" data-danger>Slett</button>
</div>
</ix-dropdown>