Hopp til hovedinnhold

Formidle endringer uten å flytte fokus (WCAG 4.1.3)

Viktige statusmeldinger må formidles til hjelpemidler uten å flytte fokus, ved hjelp av ARIA live regions.

Du legger en vare i handlekurven, og et lite tall oppdateres i hjørnet av skjermen. Du søker etter «sko», og teksten «23 resultater funnet» dukker opp over produktlisten. Du sender et skjema, og en grønn boks sier «Meldingen din er sendt!». For seende brukere er disse statusmeldingene åpenbare. Men for en skjermleserbruker - som ikke kan se at noe har endret seg på et annet sted på siden - kan de være helt usynlige.

Hva sier kravet?

WCAG 4.1.3 Statusbeskjeder krever at statusmeldinger kan formidles til brukeren via hjelpeteknologi uten at fokus flyttes til meldingen. Kravet er på nivå AA.

En statusmelding er informasjon som gis til brukeren om:

  • Suksess eller resultat av en handling (for eksempel «Varen er lagt i handlekurven»)
  • Fremdrift i en prosess (for eksempel «Laster inn... 50 %»)
  • Feil som ikke er direkte knyttet til et spesifikt felt
  • Tilgjengeligheten av informasjon (for eksempel «23 resultater funnet»)

Det sentrale poenget er at disse meldingene skal nå skjermleserbrukeren uten at fokus flyttes. Hvis du flytter fokus til meldingen, mister brukeren konteksten for hva de holdt på med. Løsningen er ARIA live regions - spesielle attributter som forteller skjermleseren at den skal annonsere endringer i et element automatisk.

Hvorfor er dette viktig?

Skjermlesere leser bare det som har fokus

En skjermleser presenterer innholdet sekvensielt. Den leser det elementet som har fokus, eller det elementet brukeren navigerer til. Endringer som skjer andre steder på siden - et tall som oppdateres i en meny, en melding som dukker opp øverst - blir ikke oppdaget med mindre de er spesielt markert.

Tenk deg at du legger noe i handlekurven, men ikke hører noen bekreftelse. Ble varen lagt til? Fungerte det? Du vet ikke, fordi skjermleseren ikke fortalte deg det. Kanskje trykker du på knappen igjen - og igjen - og ender opp med fem eksemplarer i kurven.

Toast-meldinger er spesielt problematiske

Mange moderne nettsider bruker «toast»-meldinger - små bokser som glir inn fra kanten av skjermen, vises noen sekunder, og forsvinner igjen. Disse er designet for å være midlertidige og ikke-forstyrrende for seende brukere, men uten ARIA-markup er de fullstendig usynlige for skjermleserbrukere.

Sanntidsoppdateringer

Nettsider med sanntidsinnhold - chat, varsler, lagerstatus, tidtakere - har et ekstra ansvar for å formidle oppdateringer til hjelpeteknologi. Uten riktig markering lever disse brukerne i en statisk verden mens resten av innholdet endrer seg rundt dem.

Slik oppfyller du kravet

Bruk role="status" for generelle statusmeldinger

For meldinger som bekrefter at noe har skjedd (suksess, informasjon), bruk role="status". Denne rollen har implicit aria-live="polite", som betyr at skjermleseren annonserer meldingen etter at den er ferdig med å lese det den holder på med:

<!-- Statuscontainer som finnes i DOM-en fra starten -->
<div role="status" id="handlekurv-status"></div>

<script>
function leggIHandlekurv(produkt) {
  // ... legger til produkt i kurven ...
  
  document.getElementById('handlekurv-status')
    .textContent = 
    produkt.navn + ' er lagt i handlekurven. ' +
    'Du har nå ' + antall + ' varer i kurven.';
}
</script>

Et viktig poeng: elementet med role="status" bør finnes i DOM-en fra starten. Skjermlesere fungerer best med ARIA live regions som allerede eksisterer når siden lastes, og der innholdet oppdateres dynamisk. Å legge til et helt nytt element med role="status" i DOM-en fungerer ikke like pålitelig på tvers av alle skjermlesere.

Bruk role="alert" for viktige varsler

For meldinger som krever umiddelbar oppmerksomhet - feil, advarsler, viktige varsler - bruk role="alert". Denne har implicit aria-live="assertive", som betyr at skjermleseren avbryter det den holder på med for å lese meldingen:

<div role="alert" id="feil-varsel"></div>

<script>
function visSessionVarsel() {
  document.getElementById('feil-varsel')
    .textContent = 
    'Økten din utløper om 2 minutter. ' +
    'Lagre arbeidet ditt nå.';
}
</script>

Bruk role="alert" med forsiktighet. Hvis alt er «viktig», blir ingenting viktig. Brukeren blir overveldet av avbrytelser, og det er en dårlig opplevelse.

Søkeresultater

Når brukeren søker og antall resultater vises, bør dette annonseres:

<form role="search" action="/sok" method="get">
  <label for="sok">Søk i produkter</label>
  <input type="search" id="sok" name="q">
  <button type="submit">Søk</button>
</form>

<div role="status" id="sok-status" 
  aria-live="polite">
  <!-- Oppdateres med JavaScript etter søk -->
</div>

<div id="sok-resultater">
  <!-- Resultater lastes inn her -->
</div>

<script>
function visSokeresultater(resultater) {
  const statusEl = 
    document.getElementById('sok-status');
  
  if (resultater.length === 0) {
    statusEl.textContent = 
      'Ingen resultater funnet for søket ditt. ' +
      'Prøv et annet søkeord.';
  } else {
    statusEl.textContent = 
      resultater.length + ' resultater funnet.';
  }
  
  renderResultater(resultater);
}
</script>

Fremdriftsindikatorer

For prosesser som tar tid, hold brukeren informert:

<div role="status" aria-live="polite" 
  id="opplasting-status">
</div>

<script>
function oppdaterFremdrift(prosent) {
  const statusEl = 
    document.getElementById('opplasting-status');
  
  if (prosent < 100) {
    statusEl.textContent = 
      'Laster opp fil... ' + prosent + ' prosent.';
  } else {
    statusEl.textContent = 
      'Filen er lastet opp.';
  }
}
</script>

Vær forsiktig med frekvensen - du trenger ikke annonsere hvert prosentpoeng. Oppdater hvert 25. prosentpoeng eller lignende, slik at skjermleseren ikke hakker.

Toast-meldinger med ARIA

Hvis du bruker toast-meldinger, sørg for at toast-containeren er en live region:

<div id="toast-container" 
  role="status" 
  aria-live="polite">
</div>

<script>
function visToast(melding) {
  const container = 
    document.getElementById('toast-container');
  
  const toast = document.createElement('div');
  toast.className = 'toast';
  toast.textContent = melding;
  container.appendChild(toast);
  
  setTimeout(() => {
    toast.remove();
  }, 5000);
}

// Bruk:
visToast('Innstillingene dine er lagret.');
</script>

Vanlige feil

  • Live region mangler helt - den desidert vanligste feilen. Statusmeldinger vises visuelt, men har ingen ARIA-markup, og er derfor usynlige for skjermlesere.
  • Live region som legges til dynamisk - elementet med role="status" eller aria-live settes inn i DOM-en sammen med meldingen. Mange skjermlesere ignorerer live regions som ikke fantes da siden ble lastet.
  • For aggressiv bruk av role="alert" - alle meldinger markeres som alerts, noe som fører til konstante avbrytelser. Bruk role="status" for rutinemeldinger og role="alert" kun for kritiske varsler.
  • Fremdriftsindikatorer uten tekst - en visuell laste-animasjon (spinner) uten tekstalternativ. Skjermleserbrukere vet ikke at noe lastes.
  • Statusmeldinger som forsvinner for raskt - toast-meldinger som vises i bare 2-3 sekunder, for kort tid for noen brukere å lese.
  • Tomme live regions som aldri oppdateres - containeren er på plass, men JavaScript-koden glemmer å oppdatere innholdet.

Statusbeskjeder er limet som holder brukeropplevelsen sammen for skjermleserbrukere. Uten dem navigerer disse brukerne i blinde, uten bekreftelse på at handlingene deres har effekt. Med riktig bruk av ARIA live regions gir du alle brukere den informasjonen de trenger for å bruke nettstedet trygt og effektivt.