Modal

Release dato: 26.11.2024

Sist oppdatert: 19.06.2025

Modal (også kalt dialog eller popup) er et midlertidig vindu som vises over annet innhold. Du bruker modal når du vil be brukeren ta stilling til noe viktig, vise informasjon eller gi mulighet for interaksjon, uten at de forlater den siden de er på.

Modaler bør brukes med måte. De kan oppleves forstyrrende, og må derfor ha en tydelig hensikt og være enkle å lukke.

Har du noen innspill til komponenten?Gi oss beskjed!

Test komponenten

Ønsker du å lagre dine siste endringer?

Du har lagt til endringer i distribusjonsreglene. Ønsker du å lagre dem? Where does it come from? Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. Where does it come from? Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. Where does it come from? Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.
Informasjon til deg

Viktig informasjon om din brukeropplevelse

Vi har gjort noen endringer som kan påvirke din opplevelse. Les mer for å få den nyeste informasjonen, eller lukk denne meldingen hvis du ikke ønsker flere oppdateringer nå. Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. Where does it come from? Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.

Ønsker du å lagre dine siste endringer?

Du har lagt til endringer i distribusjonsreglene. Ønsker du å lagre dem? Where does it come from? Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. Where does it come from? Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. Where does it come from? Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. Where does it come from? Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes

Relaterte komponenter

Varianter

Varianter

Modal kommer i to ulike visuelle varianter. Du velger selv hvilken variant som passer best i din løsning.

StyleBeskrivelse
SimpleFor enkle og nøytrale flater som admin-grensesnitt
SymbolLuftigere stil med lukknapp, passer for løsninger som matcher oslo.kommune.no
Simple variant av modal med enkelt kryss som lukkeknappSymbol variant av modal med gulfarget og rund lukkenapp med blått kryss i midten

Retningslinjer for bruk

Bruk modal når

  • du trenger en bekreftelse på en kritisk handling (for eksempel ved sletting eller endringer som ikke kan angres)
  • du vil vise ekstra informasjon uten å forlate siden
  • du vil vise et skjema brukeren må fylle ut umiddelbart

Unngå modal når

  • innholdet er langt eller komplekst, bruk heller en ny side
  • det er flere steg i prosessen
  • informasjonen ikke er kritisk, bruk heller accordion eller lignende

Bruk modaler med omhu

Modaler er ofte forstyrrende, og regnes sjelden som god brukeropplevelse. De bryter brukerens flyt, tar over skjermen og gir inntrykk av at noe haster, selv når det ikke gjør det.

En modal kan få brukeren til å miste tråden i oppgaven de jobber med. De vet kanskje ikke hvorfor den dukker opp, hvordan den lukkes eller om de må gjøre noe. Dette gjelder særlig for brukere med konsentrasjonsvansker, nedsatt syn eller skjermleser.

I følge Nielsen Norman Group kan modaler skape usikkerhet eller frustrasjon hvis de ikke er forventet eller blokkerer viktig innhold.

Er innholdet faktisk viktig nok til å avbryte brukeren? Og er det tydelig hva brukeren skal gjøre? Modal er en forstyrrelse. Bruk den bare når det er helt nødvendig, og gjør det tydelig hva brukeren skal gjøre.

Vi anbefaler at du tester modalen i bruk – helst med faktiske brukere – før du setter den i produksjon. Det er den beste måten å sikre at modalen hjelper, ikke hindrer.

Ikke åpne modal automatisk

En modal skal aldri vises uten at brukeren har gjort noe som tilsier det. Det må alltid være en tydelig trigger som gjør at brukeren forventer et avbrudd.

Gi brukeren en tydelig handling å utføre

En modal uten knapp eller neste steg skaper frustrasjon. Sørg for at det er tydelig hva brukeren skal gjøre, for eksempel lagre, sende inn, slette eller avbryte.

Gjør slik

Bruk modal når du vil gi mer informasjon, uten at det forstyrrer resten av oppgaven brukeren jobber med

Unngå

Unngå utydelige modaler der brukeren blir usikker på hva som skjer etter trykk eller interaksjon

Ikke bruk modaler til lange skjemaer eller mye interaksjon

Hvis modalen inneholder mange felt eller seksjoner, velg heller en egen side. Det gir bedre oversikt og navigasjon, særlig på små skjermer.

Ikke bruk modal til ukritisk informasjon

Modal passer ikke for små oppdateringer eller informasjon som kan vises på en roligere måte. Bruk inline-elementer eller infoseksjoner (for eksempel messagebox) i stedet.

Gjør slik

Bruk modal til kritiske handlinger og beskjeder

Unngå

Unngå modal ikke haster eller krever brukerens umiddelbare oppmerksomhet

Når du viser feilmeldinger i modal

Bruk komponenten alert for å vise feil, advarsler eller suksessmeldinger inne i modalen. Ikke endre bakgrunn eller tekstfarge på modalen for å signalisere alvor.

Gjør slik

Gå for å endre elementer i innholdet for å fremheve alvorlighetsgraden av en handling

Unngå

Unngå å endre fargen til modalen

Responsivitet

Når brukeren har mindre skjermplass, for eksempel på mobil, tar modaler ofte over hele visningen. Det kan føre til at brukeren mister oversikten, eller blir usikker på hva som skjer.

På mobil er det derfor ekstra viktig at modalen

  • oppleves som naturlig del av brukerflyten
  • har én tydelig handling og ikke flere valg som krever vurdering
  • er enkel å lukke med tydelig lukknapp og støtte for å bruke “Esc”/tilbake

Unngå å vise modaler med mye innhold, flere valg eller lange skjemaer på mobil. Det kan være krevende å navigere, spesielt med skjermtastatur oppe, og gir ofte en dårlig opplevelse.

Test alltid modal på mobilskjerm, i både stående og liggende visning. Pass på at innholdet ikke kuttes, at brukeren enkelt forstår hva som skjer, og at det er lett å gå tilbake.

Modaler på mobil fungerer best når de er korte, enkle og har én klar beskjed. Alt annet bør vurderes løst på en annen måte.

modal på mobil

Universell utforming

Modal er en dialogboks som vises over innholdet på siden. Den bruker HTML-elementet <dialog>, som automatisk setter fokus på det første fokuserbare elementet når modalen åpnes. I Punkt sin løsning er dette ofte lukknappen, og den får derfor autofocus. Vi anbefaler alltid å vise lukknappen, det gir forutsigbarhet og kontroll for brukeren.

Fokus skal styres riktig

Når modalen åpnes, skal fokus flyttes inn i modalen automatisk, helst til første interaktive element. Fokus må holdes inne i modalen så lenge den er åpen. Brukeren skal ikke kunne tabbe seg «bak» eller ut av den. Når modalen lukkes, skal fokus returneres til det elementet som åpnet den.

Gi brukeren en tydelig vei ut

Alle modaler må kunne lukkes med både “Esc” og en synlig lukknapp. Det gjør det enkelt å forstå hvordan man kommer seg videre, og er spesielt viktig for brukere med motoriske utfordringer.

Merk: “Esc” fungerer bare dersom du åpner modalen med den innebygde funksjonen showModal(). Dette vises i kodeeksemplene lenger ned.

Tastaturnavigasjon må fungere

Alle knapper og felt inne i modalen må kunne nås og brukes med tastatur. Hvis modalen inneholder et skjema, må submit-knappen være wrappet i <form method="dialog">. Da lukkes modalen automatisk når skjemaet sendes inn, uten at du trenger ekstra logikk.

Tittelen må være tydelig

Modalen skal alltid ha en tittel i en <h1>-tag. Dette hjelper skjermlesere med å tolke innholdet, og gir god kontekst for alle brukere.

Tilpass visning på små skjermer

På mobil og små skjermer skal modalen utvide seg og ta hele bredden. Modalen justerer seg automatisk når skjermen er smalere enn 576 px (36 rem). Vi anbefaler å teste dette i praksis, særlig hvis du har mye innhold i modalen.

Anatomi

ElementBeskrivelser
1. TittelOverskriften i modalen, gir brukeren kontekst
2. Lukke-ikonKnapp med ikon oppe til høyre, skal alltid være synlig
3. InnholdTekst, skjemaelementer, instruksjoner eller annet innhold
4. Valgfritt innhold (slot)Område for egendefinert innhold
5. HandlingerEn eller flere knapper nederst i modalen
Anatomi på Modal.

Implementasjon i kode

Hvordan ta komponenten i bruk?

import @oslokommune/punkt-elements/dist/pkt-modal.js;
import { PktModal } from '@oslokommune/punkt-react';
<script src="https://punkt-cdn.oslo.kommune.no/19/elements/pkt-modal.js" type="module"></script>

Testing

Elements: Dersom du skal skrive tester med JSDOM eller liknende er det viktig at du lar komponenten bli rendret ferdig før du tester den. Dette kan gjøres ved å kjøre denne kodelinjen før testene kjøres:

await window.customElements.whenDefined("pkt-modal");

Deklarativ vs. imperativ — velg én tilnærming

PktModal støtter to måter å åpne og lukke på:

  1. Deklarativ (anbefalt): Bruk open-prop/attributt og onClose/close-event for å styre tilstanden
  2. Imperativ: Kall showModal() / close() direkte (via ref i React, eller på elementet i Elements)

Ikke bland begge tilnærmingene på samme modal. Det native <dialog>-elementet sender ikke en hendelse når det åpnes — bare når det lukkes. Hvis du bruker open-prop for tilstandshåndtering, men også kaller showModal() imperativt, vil tilstanden bli usynkronisert, og det finnes ingen onOpen-hendelse for å fange det opp.

React: Bruk open + onClose eksklusivt, eller ref eksklusivt. Ikke kombiner dem.

Elements / HTML + JavaScript:

Deklarativt — styr med attributt og lytt på close:

<pkt-modal id="myModal" headingText="Tittel" open>...</pkt-modal>
<script>
  const modal = document.querySelector('#myModal')
  // Lukk: fjern attributten
  modal.removeAttribute('open')
  // Åpne: sett attributten
  modal.setAttribute('open', '')
  // Lytt på lukking (Esc, lukkeknapp, bakgrunn)
  modal.addEventListener('close', () => { ... })
</script>

Imperativt — kall metoder direkte:

<pkt-modal id="myModal" headingText="Tittel">...</pkt-modal>
<script>
  const modal = document.querySelector('#myModal')
  modal.showModal()
  modal.addEventListener('close', () => { ... })
</script>

Ikke bland — f.eks. ikke sett open-attributten og kall .showModal() på samme element.

Testing med jsdom

PktModal bruker det native <dialog>-elementet med showModal(). jsdom støtter ikke HTMLDialogElement (jsdom#3294) — metodene show(), showModal() og close() er ikke implementert.

Hvis du bruker Vitest eller Jest med jsdom, må du mocke disse metodene i test-setupet:

beforeEach(() => {
  HTMLDialogElement.prototype.show = vi.fn(function (this: HTMLDialogElement) {
    this.setAttribute('open', '')
  })
  HTMLDialogElement.prototype.showModal = vi.fn(function (this: HTMLDialogElement) {
    this.setAttribute('open', '')
  })
  HTMLDialogElement.prototype.close = vi.fn(function (this: HTMLDialogElement) {
    this.removeAttribute('open')
  })
})

Alternativt kan du bruke et ekte nettlesermiljø (Playwright, Cypress) for integrasjonstester som krever full dialog-funksjonalitet.

Egenskaper

PktModal

Props

Prop:
open?
Type:
boolean
Standardverdi:
false
Beskrivelse:
Deklarativ styring av modalens åpen/lukket-tilstand. Kan brukes i stedet for showModal()/close()-metodene.
Prop:
headingText?
Type:
string
Beskrivelse:
Heading tekst på modalen
Prop:
headingIconName?
Type:
icon
Beskrivelse:
Navn på ikonet som vises foran overskriften. Vises bare når headingText er satt.
Prop:
headingIconPath?
Type:
string
Beskrivelse:
Overstyr stien til ikonet i overskriften. Kan også settes globalt med window.pktIconPath.
Prop:
hideCloseButton?
Type:
boolean
Standardverdi:
false
Beskrivelse:
Gjemmer lukkeknappen. Dersom denne er satt til true, vil ikke lukkeknappen vises, og dermed er det viktig at man tilbyr en annen måte som f.eks. en knapp for å lukke modalen på.
Prop:
closeOnBackdropClick?
Type:
boolean
Standardverdi:
false
Beskrivelse:
Lukk modalen når bakgrunnen trykkes på
Prop:
closeButtonSkin?
Type:
"blue" | "yellow-filled"
Standardverdi:
"blue"
Beskrivelse:
Stil på lukkeknappen
Prop:
size?
Type:
"small" | "medium" | "large" | "fit-content"
Standardverdi:
"medium"
Beskrivelse:
Størrelsen på modalen
Prop:
variant?
Type:
"dialog" | "drawer"
Standardverdi:
"dialog"
Beskrivelse:
Standard dialog eller skuff
Prop:
drawerPosition?
Type:
"left" | "right"
Standardverdi:
"right"
Beskrivelse:
Posisjonen til skuffen
Prop:
transparentBackdrop?
Type:
boolean
Standardverdi:
false
Beskrivelse:
Bakgrunnen er gjennomsiktig
Prop:
removePadding?
Type:
boolean
Standardverdi:
false
Beskrivelse:
Fjerner paddingen rundt innholdet i modalen

Slots

Slot:
default
Beskrivelse:
Innholdet i meldingen. Her tilbyr vi støtteklasser for å style 1-3 knapper i modalen.

Events

Event:
background-click
Type:
—
Beskrivelse:
Event som trigges når bakgrunnen trykkes på
Event:
close
Type:
—
Beskrivelse:
Event som trigges når meldingsboksen lukkes