Hopp til hovedinnhold

La brukeren angre trykk og klikk (WCAG 2.5.2)

Handlinger skal ikke utføres ved bare å trykke ned museknappen, slik at brukeren kan avbryte ved å flytte pekeren bort.

Du holder mobilen i hånden og skal trykke på «Avbryt», men fingeren lander på «Slett» i stedet. Heldigvis er du vant til at ting skjer når du slipper fingeren, ikke når du trykker ned - så du drar fingeren bort før du slipper, og handlingen avbrytes. Denne muligheten til å angre et feiltrykk er noe vi tar for gitt, men den fungerer bare hvis nettstedet er bygget riktig.

Hva sier kravet?

WCAG 2.5.2 «Pekeravbrytelse» er et nivå A-krav som handler om når en handling faktisk utføres i forbindelse med klikk og trykk. Kravet sier at for funksjoner som bruker en peker (mus, finger, stylus), skal minst ett av følgende gjelde:

  • Ingen hendelse ved nedtrykk: Handlingen utføres ikke på selve nedtrykket (mousedown/touchstart), men på slipp (mouseup/touchend/click)
  • Mulighet for å avbryte: Handlingen utføres ved slipp, men brukeren kan avbryte ved å flytte pekeren bort fra elementet før de slipper
  • Mulighet for å angre: Handlingen utføres ved nedtrykk, men det finnes en mekanisme for å angre den
  • Essensiell: Nedtrykk-handlingen er essensiell for funksjonen - for eksempel et piano der lyden skal komme når du trykker ned en tangent

I praksis betyr dette: bruk standard click-hendelsen i stedet for mousedown eller touchstart. Standard click avfyres på slipp (mouseup) og bare hvis pekeren fortsatt er over elementet - noe som gir brukeren automatisk avbruddsmulighet.

Hvorfor er dette viktig?

Feiltrykk er mye vanligere enn de fleste utviklere tror. De rammer spesielt:

  • Brukere med motoriske funksjonsnedsettelser som tremor eller spasmer, der fingeren kan lande på feil sted
  • Brukere med store fingre på små skjermer der berøringsområdene er tett plassert
  • Eldre brukere med redusert presisjon i finmotorikken
  • Brukere med synshemning som kanskje ikke ser nøyaktig hvor de trykker
  • Alle som bruker mobil i bevegelse - på bussen, mens de går, i en stresset situasjon

Muligheten til å avbryte et feiltrykk er en grunnleggende sikkerhetsnett. Uten den blir destruktive handlinger (sletting, sending, kjøp) risikable for brukere som ikke kan stole på presisjonen sin. Det handler ikke bare om tilgjengelighet - det er god brukeropplevelse for alle.

Slik oppfyller du kravet

Bruk click-hendelsen, ikke mousedown

Den enkleste regelen er: bruk alltid click i stedet for mousedown for å utløse handlinger. Standard click-hendelsen i HTML avfyres først når brukeren slipper museknappen eller løfter fingeren, og bare hvis pekeren fortsatt er over elementet:

// FEIL: Handling utføres umiddelbart ved nedtrykk - ingen mulighet for avbrytelse
knapp.addEventListener('mousedown', () => {
  slettElement();
});

// RIKTIG: Handling utføres ved klikk (slipp) - brukeren kan avbryte
knapp.addEventListener('click', () => {
  slettElement();
});
<!-- HTML onclick fungerer også korrekt - det er en click-hendelse -->
<button onclick="slettElement()">Slett</button>

Touchstart vs. touchend

På mobilenheter er den tilsvarende feilen å bruke touchstart for å reagere umiddelbart ved berøring:

// FEIL: Reagerer ved berøring - ingen mulighet for avbrytelse
element.addEventListener('touchstart', () => {
  utfoerHandling();
});

// RIKTIG: Reagerer når fingeren løftes
element.addEventListener('touchend', (e) => {
  // Sjekk at fingeren fortsatt er over elementet
  const touch = e.changedTouches[0];
  const target = document.elementFromPoint(touch.clientX, touch.clientY);
  if (element.contains(target)) {
    utfoerHandling();
  }
});

// ENKLERE: Bruk click som fungerer på både mus og touch
element.addEventListener('click', () => {
  utfoerHandling();
});

Det enkleste er å bruke click-hendelsen konsekvent. Moderne nettlesere håndterer click for både mus og berøring.

Dra-og-slipp riktig

Dra-og-slipp er et tilfelle der mousedown er nødvendig for å starte operasjonen, men selve handlingen bør fullføres ved mouseup. Og hvis brukeren drar til et ugyldig område, bør elementet gå tilbake til sin opprinnelige posisjon:

let dragStartPosisjon = null;

element.addEventListener('mousedown', (e) => {
  dragStartPosisjon = { x: e.clientX, y: e.clientY };
  element.classList.add('draging');
});

document.addEventListener('mouseup', (e) => {
  if (!dragStartPosisjon) return;

  const dropTarget = document.elementFromPoint(e.clientX, e.clientY);

  if (dropTarget && dropTarget.classList.contains('gyldig-maal')) {
    fullfoerFlytting(element, dropTarget);
  } else {
    // Avbryt - flytt elementet tilbake
    tilbakestillPosisjon(element);
  }

  dragStartPosisjon = null;
  element.classList.remove('draging');
});

Bekreftelsesdialog for kritiske handlinger

For destruktive eller irreversible handlinger er en bekreftelsesdialog ekstra sikkerhet - selv om du allerede bruker click:

<button onclick="bekreftSletting()">Slett konto</button>

<dialog id="bekreftDialog">
  <h2>Er du sikker?</h2>
  <p>Denne handlingen kan ikke angres. All data vil bli permanent slettet.</p>
  <button onclick="avbryt()">Avbryt</button>
  <button onclick="slettKonto()">Ja, slett kontoen min</button>
</dialog>

<script>
function bekreftSletting() {
  document.getElementById('bekreftDialog').showModal();
}
function avbryt() {
  document.getElementById('bekreftDialog').close();
}
</script>

Angre-funksjonalitet

Hvis handlingen allerede har skjedd, kan en angre-funksjon oppfylle kravet:

function slettPost(postId) {
  const post = skjulPost(postId);

  visVarsel('Posten ble slettet', {
    handling: 'Angre',
    callback: () => {
      gjennopprettPost(post);
    },
    timeout: 10000 // 10 sekunder til å angre
  });

  // Slett permanent etter timeout
  setTimeout(() => {
    faktiskSlett(postId);
  }, 10000);
}

Vanlige feil

  • Bruk av mousedown eller touchstart for å utløse handlinger i stedet for click - den vanligste feilen, ofte gjort for å få grensesnittet til å føles «raskere»
  • Tredjepartsbiblioteker som bruker touchstart for å unngå 300ms-forsinkelsen på eldre mobilenheter - dette er ikke lenger nødvendig i moderne nettlesere
  • Dra-og-slipp uten mulighet for å avbryte - elementet flyttes permanent selv om brukeren slipper utenfor et gyldig mål
  • Spillignende grensesnitt der handlinger skjer ved nedtrykk for responstid, uten alternativ
  • Egendefinerte glidebrytere og skyveknapper som endrer verdi ved mousedown i stedet for å vente til mouseup
  • Manglende bekreftelsesdialog for destruktive handlinger som sletting av kontoer, data eller innhold

Pekeravbrytelse er et krav som de fleste nettsider oppfyller automatisk - så lenge du bruker standard HTML-elementer og click-hendelsen. Problemer oppstår nesten utelukkende når utviklere bevisst velger mousedown eller touchstart for å gjøre interaksjonen raskere. Det er sjelden verdt risikoen.