Skip to content

Commit

Permalink
docs: article about error messages (cross-agency cooperation) (#2096)
Browse files Browse the repository at this point in the history
Resolves #2093

---------

Co-authored-by: Lasse Karlsen <[email protected]>
Co-authored-by: Tobias Barsnes <[email protected]>
  • Loading branch information
3 people committed Aug 6, 2024
1 parent 8edc089 commit bb5e620
Show file tree
Hide file tree
Showing 4 changed files with 564 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
<<<<<<< HEAD:apps/storefront/app/monstre/obligatoriske-og-valgfrie-felt/page.mdx
import { Card, CardContent, Heading, Paragraph } from '@digdir/designsystemet-react';
=======
import { Card, Heading, Paragraph } from '@digdir/designsystemet-react';

import { MenuPageLayout } from '@layouts';
import { Meta, Image } from '@components';
>>>>>>> 61604693 (docs: article about error messages (cross-agency cooperation) (#2096)):apps/storefront/pages/monstre/obligatoriske-og-valgfrie-felt.mdx

import { MenuPageLayout } from '@layouts';
import { Image } from '@components';
Expand All @@ -23,15 +30,23 @@ Det er flere måter å markere obligatoriske felt på som [oppfyller kravene til
<Card
color='third'
>
<<<<<<< HEAD:apps/storefront/app/monstre/obligatoriske-og-valgfrie-felt/page.mdx
<CardContent
=======
<Card.Content
>>>>>>> 61604693 (docs: article about error messages (cross-agency cooperation) (#2096)):apps/storefront/pages/monstre/obligatoriske-og-valgfrie-felt.mdx
style={{
paddingTop: '0px',
paddingBottom: '0px'
}}
>
*Retningslinjene er utarbeidet i en tverretatlig arbeidsgruppe med deltakere fra Digdir, Nav, Skatt, Brreg og Oslo Origo. Du kan påvirke arbeidet i [Github](https://github.com/digdir/designsystemet/issues/new) eller i [#Mønster-kanalen](https://designsystemet.slack.com/archives/C05RBGB92MC/p1712751837722749)[Slack](https://join.slack.com/t/designsystemet/shared_invite/zt-2438eotl3-a4266Vd2IeqMWO8TBw5PrQ).

<<<<<<< HEAD:apps/storefront/app/monstre/obligatoriske-og-valgfrie-felt/page.mdx
</CardContent>
=======
</Card.Content>
>>>>>>> 61604693 (docs: article about error messages (cross-agency cooperation) (#2096)):apps/storefront/pages/monstre/obligatoriske-og-valgfrie-felt.mdx
</Card>

En generell retningslinje er at vi bør unngå å be om informasjon vi ikke trenger, altså unngå valgfrie felt.
Expand Down
316 changes: 316 additions & 0 deletions apps/storefront/pages/monstre/feilmeldinger.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,316 @@
import {
Card,
Heading,
Paragraph,
Accordion,
} from '@digdir/designsystemet-react';

import { Meta, Image } from '@components';
import { Contributors } from '@blog';
import { MenuPageLayout } from '@layouts';

<Meta
title='Feilmeldinger i skjema'
description='Slik forteller du brukeren at noe har gått galt eller mangler i et skjema.'
/>

export default ({ children }) => (
<MenuPageLayout
content={children}
data={{
title: 'Brukerutløste feilmeldinger',
date: '28. juni 2024',
}}
/>
);

## Innledning

Feilmeldinger kan komme fra systemet eller være utløst av noe brukerne har gjort. Denne artikkelen handler om brukerutløste feilmeldinger i selvbetjeningsløsninger og skjema. Hvordan kan vi unngå å gi feilmeldinger, og hvordan kan vi hjelpe brukerne å komme seg videre når det likevel har oppstått en feil?

Når brukerne har gjort en feil som hindrer dem i å komme videre, skal vi varsle dem om feilen slik at de kan rette opp:

- Beskriv problemet på en lettforståelig måte.
- Forklar hva brukerne må gjøre for å komme videre.
- Passe på at feilmeldingen er lett synlig.

Feilmeldinger kan være knyttet til ett enkelt felt eller til flere. Vi viser en oppsummering av flere feil hvis brukeren forsøker å gå videre uten å ha fylt ut alt.

### Feilmeldinger på enkeltfelt

Vi skal kunne vise feilmeldinger sammen med alle typer felt i et skjema. Meldingen skal stå nært feltet som feiler.

<Image
src='/img/errormessage-co-1.png'
alt='Skjermbilde av skjema med en feilmelding. Brukeren har skrevet "fdgdfgfdg" inn i et felt for fødselsnummer. Feilmeldingen sier at Fødselsnummer skal inneholde 11 siffer.'
boxShadow={false}
/>

### Oppsummering av flere feilmeldinger

En oppsummering kan gjelde for én eller flere feil. Hvis brukerne prøver å gå videre uten å ha fylt ut alt, eller de har gjort feil, oppsummerer vi like over Neste/Send inn-knappen.

Vi anbefaler å vise oppsummeringen i nærheten av Neste-knappen for at brukerne skal forstå sammenhengen mellom feilen og hvorfor de blir hindret i å gå videre. I noen tilfeller kan det likevel være bedre å vise oppsummeringen i toppen, for eksempel hvis

- den tekniske løsningen laster siden på nytt når brukerne velger Neste
- brukerne har vært ute av et skjema og går inn igjen
- løsningen ikke stopper brukerne fra å gå til neste side selv om de har feil på en side

Pass på at

- oppsummeringen viser alle feilmeldingene som gjelder for siden eller trinnet
- brukerne kan gå direkte til feilene de må rette opp, og fokuset blir flyttet dit
- lenkene i oppsummeringen stemmer med feilmeldingene de lenker til
- du lenker til den første av flere feil
- feilene forsvinner fra oppsummeringen etter hvert som brukerne fikser dem
- feilmeldingen i oppsummeringen har med nøkkelord fra ledeteksten

<Image
src='/img/errormessage-co-3.png'
alt='Skjermbilde av skjema med en feilmelding. Brukeren har skrevet "fdgdfgfdg" inn i et felt for fødselsnummer. Feilmeldingen sier at Fødselsnummer skal inneholde 11 siffer.'
boxShadow={false}
/>

### Det er best om vi kan unngå å gi feilmeldinger

Når vi planlegger en løsning, bør målet være å hindre at det oppstår feil. Disse punktene kan hjelpe i planleggingen:

- Gi all relevant informasjon før brukerne starter, i klart og tydelig språk.
- Bruk ledetekster og beskrivelser for å hjelpe brukerne underveis.
- Unngå hjelpetekster bak spørsmålstegn om du kan, men bruk dem om nødvendig.
- Gi brukerne mulighet til å endre svar i felt eller gå tilbake.
- La brukerne ta en pause i utfyllingen eller avbryte den.
- Sørg for at feltene godtar ulik formatering, for eksempel for datoer og telefonnummer.
- Legg inn en bestemt rekkefølge på svaralternativene, for å hindre at brukeren tar valg som fører til feil.
- Vis informasjon om maks. antall tegn under ledeteksten hvis feltet har tegnbegrensning.

### Ulike typer feilmeldinger

#### Systemgenererte meldinger

Vi bruker systemmeldinger, eller systemvarsler, for å varsle brukeren om feil i systemet eller gi dem viktig informasjon de bør få med seg. Vi har en [egen artikkel om systemvarsler](/monstre/systemvarsler).

#### Infomeldinger til brukeren

Infomeldinger som vises på grunn av noe brukerne gjør, stopper ikke brukerne fra å sende inn eller gå videre til neste steg.

Vi viser infomeldinger når vi skal informere om konsekvenser av et valg. Slike meldinger kan vi for eksempel presentere i en alert av typen "info" eller "success". Disse meldingene vises etter at brukeren har oppgitt informasjon i et skjemafelt, og oppfører seg på samme måte som feilmeldinger.

Eksempler:

- Du starter en bedrift og skal registrere navnet. Du får beskjed om at bedriftsnavnet allerede er i bruk av noen andre. Du kan bruke navnet du har valgt, men du kan få problemer med domenenavn eller at foretaket ditt blir forvekslet med et annet.
- Du gjør et valg i et søknadskjema som fører til lengre behandlingstid. Du får en infomelding om lengre ventetid.

## Språk

### Skriv gode feilmeldinger

Den viktigste jobben til en feilmelding er å hjelpe brukerne videre:

- Skriv vennlig, klart og tydelig.
- Hold feilmeldingen så kort som mulig.
- Vær konkret. Hvis vi skriver “Feltet er ikke fylt ut korrekt”, får brukeren ingen forklaring på hva som er feil.
- Gjenta nøkkelord fra ledeteksten/feltnavnet så tidlig som mulig i feilmeldingen.

Noen tekniske løsninger gjør at vi kan ta inn feltnavnet som en variabel i feilmeldinger, da blir feltnavnet i ubestemt form, som i disse eksemplene:

- “Postnummer må ha 4 siffer”
- "Fødselsnummer må ha 11 siffer"
- “Velg minst ett leveringsalternativ”

Hvis løsningen ikke tar inn feltnavnet som variabel i feilmeldinger, anbefaler vi å skrive substantivet med bestemt form: Postnummeret må ha fire siffer.

## Design og opplevelse

### Utseendet på feilmeldinger

Når det oppstår feil i et felt er det viktig at feltet blir godt synlig, slik at det er lett for brukerne å se hvor de må fylle ut eller rette opp noe.

<Image
src='/img/errormessage-design.png'
alt='Et skjemafelt som viser feil på informasjonen som er fylt ut. På feltet blir de visuelle elementene som skiller det fra et vanlig felt fremhevet: Det er tykkere kant rundt feltet, det er farget rødt og det er en rød tekst med et tilhørende fareikon som beskriver feilen på feltet.'
boxShadow={false}
/>

Når den tekniske løsningen sjekker for feil, det vi kaller validerer, ønsker vi å vise hvilke felt som har feil. Til det kan vi bruke flere virkemidler.

#### Visuelle endringer

Vis feilmeldingsteksten nært feltet det gjelder. Vi anbefaler å ha med et ikon som en visuell indikator i tillegg til tekst. For skjemakomponenter som tillater det, kan vi også endre tykkelsen på rammen rundt, som vist i eksempelet over.

#### Fargevalg

Vi bruker rød som varselfarge for feil, det vi si at feltet og selve feilmeldingen blir røde. Dette er et godt etablert mønster, som hjelper med å skille feltet fra andre felt.
Feltet må ha 3:1 kontrast til bakgrunnsfargen. Hvis vi også bruker rød tekst til feilmeldingen, må den minst ha kontrasten 4.5:1. [Les mer om kontraster hos Tilsynet for universell utforming av IKT.](https://www.uutilsynet.no/veiledning/kontrast/48)

#### Slik plasserer vi en feilmelding

Vi viser feilmeldingen under feltet med feil. Dette er det vanligste mønsteret, selv om det også diskuteres om den skal stå mellom ledeteksten og feltet.

<Card
color='first'
>
<Card.Content
style={{
paddingTop: '0px',
paddingBottom: '0px'
}}
>
Merk: Vi ønsker å holde oss oppdatert om andre anbefalinger om plassering, og har [pågående diskusjon om dette på Git](https://github.com/digdir/designsystemet/discussions/1684#discussioncomment-9339006).

</Card.Content>
</Card>

### Når skal vi vise en feilmelding?

Vi kan vise feilmeldinger når brukerne forlater feltet, når de velger å gå videre, eller sender inn. Vi unngår å vise feilmeldinger mens brukeren fyller ut et felt.

Når brukerne har gjort en feil når de fyller ut et felt og de går videre, viser vi feilmeldinger når vi kan se at brukeren ikke har fylt ut det vi forventer. Et eksempel kan være at de har lagt inn bokstaver i et fødselsnummer, eller at en e-postadresse mangler krøllalfa (@).

Brukerne bør ikke få feilmelding for et tomt obligatorisk felt før de går til neste side eller sender inn skjemaet. Vi vet ikke alltid når brukeren er ferdig med å fylle ut feltene, så da venter vi til brukeren selv er klar til å gå videre. Det er spesielt viktig når brukere benytter tastaturet til å navigere i løsningen.

### Kryssvalidering

Noen ganger vil det brukeren velger i ett eller flere felt påvirke felt som kommer senere i skjemaet. For eksempel kan et valg brukerne gjør i en radiogruppe, gjøre at et frivillig felt lenger ut i skjemaet blir obligatorisk. Et valg på ett sted kan også gjøre at et valg et annet sted må være innenfor en viss verdi. I slike tilfeller snakker vi om kryssvalidering.

Her må vi gjøre det så tydelig som mulig for brukeren at flere felt påvirker hverandre:

- Merk alle feltene visuelt og med feilmelding.
- Forklar hva som utløste feilen. Vær tydelig på at feilen skyldes kryssvalidering.
- Fortell brukerne hva de kan gjøre for å rette feilen.

#### Feilmeldinger som gjelder flere felt

I dette eksempelet har vi en gruppe med felt, der brukeren ikke nødvendigvis har alle opplysningene, men må fylle ut minst ett felt.

<Accordion
color='neutral'
>
<Accordion.Item>
<Accordion.Header level={3}>Eksempel på feilmelding som gjelder flere felt</Accordion.Header>
<Accordion.Content
style={{
paddingTop: '0px',
paddingBottom: '0px',
maxWidth: '780px'
}}>

Videoen under viser at brukeren forsøker å gå videre uten å ha fyllt ut minst ett felt, som er påkrevd. Alle feltene i gruppen blir da røde og en feilmelding vises i bunnen.

<video
controls
autoplay
width='100%'
loop
>
<source
src='/img/error-message-group-error.mp4'
type='video/mp4'
/>
</video>

Hadde det vært bare en feil i gruppen, ville feilmeldingen vist på vanlig måte under kun et av feltene, uten at hele gruppen ble rød.

<Image
src='/img/errormessage-co-22b.png'
alt='Skjermbilde av skjema med en gruppe av felter. Brukeren har fylt ut minst ett felt, men har en feil i utfyllingen. Feilmeldingen vises da på vanlig måte under det aktuelle feltet. '
boxShadow={false}
/>

</Accordion.Content>

</Accordion.Item>
</Accordion>

## Kode

### Feilmeldinger og tilgjengelighet

Det er flere WCAG-kriterier som gjelder for feilmeldinger. Vi har tatt hensyn til disse i arbeidet med denne artikkelen. Hvis du vil vite mer om det, kan du lese tolkningene av WCAG-kravene hos Tilsynet for universell utforming av IKT.

**Relevante WCAG-krav:**

- [3.3.1 Identifikasjon av feil](https://www.uutilsynet.no/wcag-standarden/331-identifikasjon-av-feil-niva/116)
- [3.3.3 Forslag ved feil](https://www.uutilsynet.no/wcag-standarden/333-forslag-ved-feil-niva-aa/118)
- [1.4.3 Kontrast (minimum)](https://www.uutilsynet.no/wcag-standarden/143-kontrast-minimum-niva-aa/95)
- [1.4.11 kontrast for ikke-tekstlig innhold](https://www.uutilsynet.no/wcag-standarden/1411-kontrast-ikke-tekstlig-innhold-niva-aa/145)

### Ikke deaktiver submit-knappen

Vi bruker ikke deaktivert "Gå videre/Send inn"-knapp til å validere skjema. Noen brukere forstår ikke hvorfor knappen er deaktivert og blir forvirret. Brukere med nedsatt syn kan slite med å finne knappen og tro at skjemaet har tekniske problemer. Hvis brukerne prøver å gå videre mens det fortsatt er feil i skjemaet, kan vi heller vise en oppsummerende feilmelding over "Gå videre/Send inn"-knappen.

### HTML og Aria

For at alle brukere skal oppfatte feilmeldinger, er det viktig med et tydelig forhold mellom feilmeldingene og feltene de tilhører, også for dem som ser på innhold med ulike hjelpemidler.

Vi kan bruke disse aria-attributtene og rollene:

- Vi setter `aria-invalid="true"` på felt med feil, for å si fra om at det er en feil der.
- Vi bruker `aria-describedby` for å koble feilmelding til feltet.

<Card
color='first'
>
<Card.Content
style={{
paddingTop: '0px',
paddingBottom: '0px'
}}
>
Vi unngår inntill videre å bruke `aria-errormessage` da den ikke har full støtte av hjelpemidler per nå. Men vi kommer til å oppdatere retningslinjene om støtten blir bedre i fremtiden. [Se diskusjon på github](https://github.com/digdir/designsystemet/discussions/1684)

</Card.Content>
</Card>

### Gi automatiske beskjeder

Vi kan også gi automatiske beskjeder når vi vil at brukeren så snart som mulig skal få opplest viktig informasjon. Det kan for eksempel være når det blir en stor visuell endring, eller nytt innhold.

For feilmeldinger som dukker opp dynamisk må vi bruke `aria-live` for at meldingen skal bli lest opp av skjermlesere. Pass godt på om du setter `aria-live` til å være `assertive` eller `polite`. I de fleste tilfeller er det best å bruke `polite`, for da venter skjermleseren med å lese opp feilmeldingen til den er ferdig med å lese opp innholdet.

## Kilder

- [Help users to Recover from validation errors, GovUK](https://design-system.service.gov.uk/patterns/validation/)
- [Designing Better Error Messages UX, Smashing Magazine/Vitaly Friedman](https://www.smashingmagazine.com/2022/08/error-messages-ux-design)
- [Formidle feil i skjema, UU-tilsynet](https://www.uutilsynet.no/veiledning/skjema/38#formidle_feil_i_skjema)
- [Use forgiving formatting, NN Group](https://www.nngroup.com/articles/slips/)
- [Error Messages Guidelines, NN Group](https://www.nngroup.com/articles/error-message-guidelines/)
- [How to Report Errors in Forms, NN Group](https://www.nngroup.com/articles/errors-forms-design-guidelines/)
- [Suksesskriterium 3.3.1 Identifikasjon av feil](https://www.w3.org/Translations/WCAG21-no/#error-identification)
- [Suksesskriterium 3.3.3 Forslag ved feil](https://www.w3.org/Translations/WCAG21-no/#error-suggestion)
- [Skjemavalidering, Aksel](https://aksel.nav.no/god-praksis/artikler/skjemavalidering)
- [Fejlmeddelelser, Fælles designsystem](https://designsystem.dk/komponenter/fejlmeddelelser/)

<br />
<br />

<Card
color='third'
>
<Card.Content
style={{
paddingTop: '0px',
paddingBottom: '0px'
}}
>
Retningslinjene er utarbeidet i en tverretatlig arbeidsgruppe med deltakere fra Digdir, Nav, Skatt, Brreg, Politiet, KS DIF og Oslo kommune. Du kan påvirke arbeidet i [Github](https://github.com/digdir/designsystemet/discussions/1684) eller i [#Mønster-kanalen](https://designsystemet.slack.com/archives/C05RBGB92MC/p1712751837722749)[Slack](https://join.slack.com/t/designsystemet/shared_invite/zt-2438eotl3-a4266Vd2IeqMWO8TBw5PrQ).

</Card.Content>
</Card>
<Contributors
authors={[
'Roy Halvor Frimanslund (Brreg)',
'Astrid Eline Øksnes (Politiet)',
'Bernard Tommerbakke (Oslo Kommune)',
'Kari Breidal (NAV)',
'Lasse Febakke Straum (Digdir)',
'Marianne Røsvik (Digdir)',
'Marianne Nordberg (KS)',
'Camilla Orten (SKD)',
'Gørild Døhl (Digdir)',
]}
/>
<br />
<br />
<br />
---
46 changes: 46 additions & 0 deletions apps/storefront/pages/monstre/systemvarsler.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Card, Heading, Paragraph } from '@digdir/designsystemet-react';

import { Meta, Image } from '@components';
import { MenuPageLayout } from '@layouts';

<Meta
title='Systemvarsler'
description='..'
/>

export default ({ children }) => (
<MenuPageLayout
content={children}
data={{
title: 'Systemvarsler',
date: '4. juni 2024',
}}
/>
);

<Card
color='third'
>
<Card.Content
style={{
paddingTop: '0px',
paddingBottom: '0px'
}}
>
*Retningslinjene er under arbeid fra 5. juni 2024 i en tverretatlig arbeidsgruppe med deltakere fra Digdir, Nav, Skatt, Brreg, Politiet, KS DIF og Oslo kommune. Alle er velkommen til å påvirke arbeidet i [Github](https://github.com/digdir/designsystemet/discussions/2083) eller i [#Mønster-kanalen](https://designsystemet.slack.com/archives/C05RBGB92MC/p1712751837722749)[Slack](https://join.slack.com/t/designsystemet/shared_invite/zt-2438eotl3-a4266Vd2IeqMWO8TBw5PrQ).

</Card.Content>
</Card>

Systemvarsler brukes for å varsle brukeren enten om feil i systemet eller holde dem informert om viktige ting de bør få med seg. Vi bruker dem til feil som ikke tilhører et skjemaelement, og som ikke validerer brukerens inndata. De bør derfor ha et annet utseende enn [brukerutløste feil](/monstre/feilmeldinger).

Systemvarsler kan for eksempel komme i form av [`alert`](https://storybook.designsystemet.no/?path=/docs/komponenter-alert--docs), `toast`, [`modal`](https://storybook.designsystemet.no/?path=/docs/komponenter-modal--docs) eller [`popover`](https://storybook.designsystemet.no/?path=/docs/komponenter-popover--docs).

Eksempler på varsler:

- Tjenesten vår er dessverre nede, men vi jobber med saken. Prøv igjen om litt. Hvis du fortsatt har problemer, kan du ta kontakt med oss.
- Det kan se ut som du ikke er koblet til internett. Sjekk tilkoblingen din og prøv igjen.
- Tjenesten vil være nede onsdag 24. juni 2029 mellom klokken 04-06.
- Du har nå tatt i bruk den nyeste versjonen av tjenesten. Du kan bytte tilbake til den gamle versjonen ved å klikke her.
- Du har ikke foretatt deg noe på en stund, og påloggingen er i ferd med å utløpe. Du vil bli logget ut om 5 minutter. Arbeidet ditt er lagret.
- Er du sikker på at du vil avbryte nå? Du kan miste arbeidet du allerede har gjort.
Loading

0 comments on commit bb5e620

Please sign in to comment.