# Animasjon

## Hva det er

En animasjon på nettet er som oftest en CSS-animasjon: en navngitt rekke nøkkelbilder (keyframes),
skrevet én gang i en `@keyframes`-regel og koblet til et element gjennom `animation`-egenskapene.
W3C-spesifikasjonen CSS Animations Level 1 beskriver mekanismen som en måte å animere verdiene til
CSS-egenskaper over tid ved hjelp av nøkkelbilder. Animerte bilder, video og tegning på canvas
beveger seg også, men denne artikkelen holder seg til den deklarative typen.

Hvert nøkkelbilde angir egenskapsverdier på et punkt i forløpet: `from` eller `0%` ved starten, `to`
eller `100%` ved slutten, og så mange prosentpunkter imellom som du trenger. Nettleseren fyller inn
verdiene mellom dem. De andre animasjonsegenskapene bestemmer hvor lenge ett gjennomløp varer, hvor
mange ganger det gjentas, om annethvert gjennomløp spilles baklengs, og om animasjonen kjører eller
står på pause. Et antall gjentakelser satt til `infinite` betyr med spesifikasjonens ord at
animasjonen gjentas for alltid. `animation-fill-mode` avgjør hva som vises utenfor selve forløpet:
med `none` har animasjonen ingen virkning da, `backwards` bruker det første nøkkelbildet under en
eventuell forsinkelse, og `forwards` beholder verdiene animasjonen sluttet på.

En overgang (transition) er den nære slektningen. Der en endret egenskapsverdi normalt ville vist
seg med en gang, sprer CSS Transitions endringen over en fastsatt varighet. CSS Animations trekker
selv grensen mellom de to: overganger utløses implisitt når en egenskapsverdi endres, mens
animasjoner kjøres eksplisitt når animasjonsegenskapene tas i bruk. En lenke som toner over til en
annen farge når pekeren holdes over den, er en overgang. En lastesnurr som går rundt enten noe har
endret seg eller ikke, er en animasjon.

En nyere spesifikasjon, Scroll-driven Animations, bytter ut klokken med selve siden. En animasjon
koblet til en tidslinje for rullefremdrift går framover når en rullebeholder rulles, fra 0 % ved
starten av det rullbare området til 100 % ved slutten. Når de to posisjonene faller sammen, fordi
det finnes ingenting å rulle, kaller spesifikasjonen tidslinjen inaktiv.

## Hvorfor det er viktig

Bevegelse trekker oppmerksomhet, og det er både grunnen til å bruke den og problemet med den.

**For noen lesere er den fysisk ubehagelig.** Forklaringsdokumentet (Understanding) for
suksesskriteriet 2.3.3 i WCAG 2.2 beskriver hvordan elementer som beveger seg mens en side rulles,
kan utløse reaksjoner hos folk med vestibulære lidelser, altså forstyrrelser i det indre øret:
svimmelhet, kvalme og hodepine. Dokumentet nevner parallakserulling, der bakgrunnen beveger seg i et
annet tempo enn forgrunnen, som en animasjon som ofte er unødvendig, og påpeker at virkningen kan
være så kraftig at personen trenger sengeleie for å komme seg.

**Leseren kan si fra, og siden kan spørre.** Media Queries Level 5 definerer
`prefers-reduced-motion`, en mediefunksjon med to verdier. `reduce` betyr at leseren har bedt
systemet om et grensesnitt som fjerner eller erstatter de typene bevegelsesbasert animasjon som gir
ubehag for folk med vestibulær bevegelsesfølsomhet, eller som distraherer folk med
oppmerksomhetsvansker. `no-preference` betyr at det ikke er kjent noen preferanse, og verdien regnes
som usann når funksjonen testes alene.

**To suksesskriterier dekker det.** 2.2.2 Pause, stopp, skjul, på nivå A, gjelder innhold som
beveger seg, blinker eller ruller, starter automatisk, varer i mer enn fem sekunder og vises sammen
med annet innhold: leseren trenger en måte å pause, stoppe eller skjule det på, med mindre
bevegelsen er nødvendig. Kravet gjelder alt på siden, og en animasjon som bare stopper mens fokus
ligger på den, teller ikke som en pause. 2.3.3 Animasjon fra interaksjoner, på nivå AAA, ber om at
bevegelsesanimasjon som utløses av en interaksjon, kan slås av, med mindre den er nødvendig.
Forklaringsdokumentet nevner innstillingen for redusert bevegelse i nettleseren eller
operativsystemet som én måte å oppfylle kriteriet på.

**Bevegelse er bare én type endring.** WCAG definerer bevegelsesanimasjon som steg lagt inn mellom
tilstander for å skape en illusjon av bevegelse eller en følelse av jevn overgang. Et element som
glir på plass eller endrer størrelse idet det dukker opp, er animert. Et element som dukker opp
momentant, er det ikke. En endring av farge eller opasitet som lar elementets oppfattede størrelse,
form og posisjon være i fred, faller utenfor definisjonen, og derfor betyr redusert bevegelse ikke
at hver eneste toning må fryses.

## Slik ser det ut i praksis

Den tydeligste lærdommen begynner med en regel som så ferdig ut. Nettstedet respekterte
innstillingen for redusert bevegelse med én universell regel som slo av alle overganger. Den så
fullstendig ut og besto linteren, men med en emulert innstilling animerte elleve selektorer
fortsatt. Arbeidet som
[gjorde innstillingen for redusert bevegelse ærlig](/nb/portfolio/made-reduced-motion-honest-135/),
sporet årsaken til spesifisitet: en universell selektor taper mot enhver regel som har en klasse, og
det gjelder hver gjennomtenkte animasjon på siden. Alt som beveger seg, ligger nå i én sen del av
stilarket, og en linter avviser en transform med overgang alle andre steder. Skillet regelen
trekker, er redusert bevegelse og ikke farge, så en fargeovergang består, mens en overgang på
bevegelse blir avvist. Bevegelse uttrykkes dessuten som en overgang og ikke som en
keyframe-animasjon, fordi den første er triviell å avbryte og den andre ikke er det. Som siden sier
det: en regel som taper på spesifisitet, feiler i det stille.

Rullestyrt bevegelse har en egen feiltilstand. Blant de
[11 feilene i universell utforming som nettleseren meldte var i orden](/nb/portfolio/fixed-11-accessibility-defects-the-browser-called-healthy-131/)
var en rullestyrt animasjon, inaktiv på en side for kort til å rulle, som hadde klippet bunnteksten
permanent bort på tre sider. De automatiske reglene hadde godkjent den, fordi feilen lå i hvordan
siden ble gjengitt, og ikke i oppmerkingen.

En linter kan gjøre sjekken umulig å hoppe over. Et
[designsystem med 48 tokens](/nb/portfolio/built-a-48-token-design-system-160/),
bygd på plattformens eget glassmateriale, har bevegelse som én av sine seks tokengrupper, og
linteren avviser en animasjon som er deklarert uten å respektere innstillingen for redusert
bevegelse. Siden gir grunnen: en animasjon legges til i et øyeblikk av finpuss, sjekken av
innstillingen er den delen som hoppes over, og derfor gjør regelen det umulig å skrive animasjonen
uten den.

Stilarkene til dette nettstedet viser de samme vanene andre steder. De to tannhjulene i toppfeltet
går rundt i sløyfer på 60 og 96 sekunder, og begge settes til `animation: none` under `reduce`.
Parallaksen deres, som følger rullingen, er sikret to ganger: inne i
`prefers-reduced-motion: no-preference` og inne i en `@supports`-test for
`animation-timeline: scroll()`. I en nettleser som mangler funksjonen, blir tannhjulene stående der
de er, og kommentaren i koden kaller den reserveløsningen selve designet. I bunnteksten henter
blokken med opphavsrettsmerknaden sin skjulte starttilstand fra animasjonens bakoverfylling
(backwards fill) og ikke fra en deklarert `opacity: 0`. Kommentaren forklarer hvorfor: en inaktiv
tidslinje har ingen virkning i det hele tatt, og den gamle `opacity: 0` hadde skjult
opphavsrettsmerknaden på hver kort side.

## Hvor det går galt

- **Av-knappen taper i kaskaden.** En generell `transition: none` på den universelle selektoren har
  nesten null spesifisitet, så hver regel med en klasse fortsetter å bevege seg, og ingenting melder
  fra om det. En blokk plassert etter reglene den skal slå, som navngir selektorene som beveger seg,
  gjør at stillstanden vinner.
- **Innstillingen kommer på plass senere, eller aldri.** En animasjon i grunnstilen beveger seg for
  alle til noen husker å avbryte den. Deklarerer du den inne i
  `@media (prefers-reduced-motion: no-preference)`, blir stillstand standarden.
- **En scroll-tidslinje møter en side med ingenting å rulle.** Tidslinjen er inaktiv og animasjonen
  gjør ingenting, så en starttilstand skrevet inn i grunnstilen, f.eks. en `opacity: 0` som venter
  på å bli animert bort, blir stående. En starttilstand som kommer fra bakoverfyllingen, forsvinner
  sammen med animasjonen.
- **En nøkkelbildeverdi nettleseren avviser, faller bort i det stille.** Spesifikasjonen sier at en
  egenskap som er angitt, men ugyldig i et nøkkelbilde, animeres som om det nøkkelbildet ikke
  fantes. En feilstavet verdi hopper over et steg, og ingen feilmelding sier fra.
- **En dekorativ sløyfe går og går, og leseren får aldri stoppet den.** En `infinite`-animasjon som
  starter når siden lastes, ved siden av teksten, faller inn under 2.2.2 så snart den passerer fem
  sekunder. En pauseknapp, eller en slutt innen fem sekunder, oppfyller kravet.
- **«Reduser» leses som «fjern alt».** Å kutte hver tilstandsendring kan ta informasjon med seg
  sammen med bevegelsen. Viser du den nye tilstanden momentant, eller med en toning, beholder du
  informasjonen og dropper bevegelsen.

## Les mer

- [CSS Animations Level 1](https://www.w3.org/TR/css-animations-1/)
  — `@keyframes`-regelen, animasjonsegenskapene, fyllmodusene og hendelsene en animasjon sender.
- [CSS Transitions Level 1](https://www.w3.org/TR/css-transitions-1/)
  — hvordan en endret egenskapsverdi spres over en varighet i stedet for å slå inn med en gang.
- [Scroll-driven Animations](https://www.w3.org/TR/scroll-animations-1/)
  — tidslinjer for rullefremdrift, notasjonen `scroll()` og tilfellene der en tidslinje er
  inaktiv.
- [Media Queries Level 5: prefers-reduced-motion](https://www.w3.org/TR/mediaqueries-5/#prefers-reduced-motion)
  — de to verdiene, og hva en leser som velger `reduce`, ber om.
- [Understanding SC 2.2.2: Pause, Stop, Hide](https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html)
  — grensen på fem sekunder, hva som regnes som automatisk start, og hvilke pausemekanismer som
  holder.
- [Understanding SC 2.3.3: Animation from Interactions](https://www.w3.org/WAI/WCAG22/Understanding/animation-from-interactions.html)
  — vestibulære reaksjoner, parallakse, og innstillingen for redusert bevegelse som én måte å
  oppfylle kriteriet på.

<https://engineer.company/nb/glossary/animation/>
