# Animation

## Vad det är

På webben är en animation oftast en CSS-animation: en namngiven följd av nyckelbilder (keyframes)
som skrivs en gång i en `@keyframes`-regel och kopplas till ett element genom egenskaperna
`animation`. W3C:s specifikation CSS Animations Level 1 beskriver mekanismen som ett sätt att
animera värdena hos egenskaper i CSS över tid med hjälp av nyckelbilder. Animerade bilder, video och
ritning på en canvas rör sig också, men den här artikeln följer den deklarativa sorten.

Varje nyckelbild anger egenskapernas värden vid en punkt i förloppet: `from` eller `0%` i början,
`to` eller `100%` i slutet och valfria procenttal däremellan. Webbläsaren räknar fram värdena mellan
dem. De övriga animationsegenskaperna styr hur länge ett varv varar, hur många gånger det upprepas,
om vartannat varv spelas baklänges och om animationen körs eller är pausad. Antalet `infinite`
betyder, med specifikationens ord, att animationen upprepas för evigt. `animation-fill-mode` avgör
vad som syns utanför förloppet: med `none` har animationen ingen verkan då, `backwards` tillämpar
den första nyckelbilden under en eventuell fördröjning, och `forwards` behåller värdena som den
slutade på.

En övergång (transition) är den nära släktingen. Där ett ändrat egenskapsvärde annars skulle synas
direkt sprider CSS Transitions ut ändringen över en angiven tid. CSS Animations drar gränsen mellan
de två: övergångar utlöses underförstått när ett egenskapsvärde ändras, medan animationer körs
uttryckligen när animationsegenskaperna tillämpas. En länk som tonar sin färg när pekaren hålls
över den är en övergång. En laddningssnurra som snurrar vare sig något har ändrats eller inte är en
animation.

En nyare specifikation, Scroll-driven Animations, byter ut klockan mot själva sidan. En animation
som är kopplad till en tidslinje för rullningsförlopp (scroll progress timeline) går framåt när en
rullningsbehållare rullas, från 0 % i början av det rullbara intervallet till 100 % i slutet. När de
två lägena sammanfaller, eftersom det inte finns något att rulla, kallar specifikationen
tidslinjen inaktiv.

## Varför det spelar roll

Rörelse drar till sig uppmärksamhet, och det är både skälet att använda den och problemet med den.

**För en del läsare är den fysiskt obehaglig.** Förklaringsdokumentet (Understanding) till
framgångskriteriet 2.3.3 i WCAG 2.2 beskriver hur element som rör sig när en sida rullas kan utlösa
reaktioner hos personer med vestibulära störningar, alltså besvär från balansorganet i innerörat:
yrsel, illamående och huvudvärk. Dokumentet nämner parallaxrullning, där bakgrunden rör sig i en
annan takt än förgrunden, som en animation som ofta inte är nödvändig, och påpekar att besvären kan
bli så svåra att den drabbade behöver sängvila för att återhämta sig.

**Läsaren kan säga ifrån, och sidan kan fråga.** Media Queries Level 5 definierar
`prefers-reduced-motion`, en mediefunktion med två värden. `reduce` betyder att läsaren har bett
systemet om ett gränssnitt som tar bort eller ersätter de typer av rörelsebaserad animation som
orsakar obehag för personer med vestibulär rörelsekänslighet eller distraherar personer med
uppmärksamhetsstörningar. `no-preference` betyder att ingen preferens är känd, och värdet räknas som
falskt när funktionen testas ensam.

**Två framgångskriterier täcker det.** 2.2.2 Pause, Stop, Hide, på nivå A, gäller innehåll som rör
sig, blinkar eller rullar, som startar automatiskt, varar längre än fem sekunder och visas
tillsammans med annat innehåll: läsaren behöver ett sätt att pausa, stoppa eller dölja det, om inte
rörelsen är nödvändig. Kriteriet gäller allt på sidan, och en animation som stannar bara medan
fokus vilar på den räknas inte som en paus. 2.3.3 Animation from Interactions, på nivå AAA, kräver
att rörelseanimation som utlöses av en interaktion går att stänga av, om den inte är nödvändig.
Förklaringsdokumentet nämner webbläsarens eller operativsystemets inställning för minskad rörelse
som ett sätt att uppfylla kriteriet.

**Rörelse är en snävare kategori än förändring.** WCAG definierar rörelseanimation som steg som
läggs till mellan två tillstånd för att skapa en illusion av rörelse eller en känsla av mjuk
övergång. Ett element som glider på plats eller ändrar storlek när det visas är animerat. Ett som
dyker upp direkt är det inte. En ändring av färg eller opacitet som lämnar elementets upplevda
storlek, form och läge i fred faller utanför definitionen, och därför betyder minskad rörelse inte
att varje toning ska frysas.

## Så ser det ut i praktiken

Den tydligaste lärdomen börjar med en regel som såg färdig ut. Webbplatsen respekterade
inställningen för minskad rörelse med en enda universell regel som stängde av alla övergångar. Den
såg fullständig ut och passerade lintern, men under en emulerad inställning animerades fortfarande
elva selektorer. Arbetet som
[gjorde inställningen för minskad rörelse ärlig](/sv/portfolio/made-reduced-motion-honest-135/)
spårade orsaken till specificitet: en universell selektor förlorar mot varje regel som bär en
klass, och det är varje genomtänkt animation på sidan. Allt som rör sig ligger nu i en del av
stilmallen som kommer sent, och en linter underkänner en transform med övergång var som helst
annars. Gränsen som regeln drar är minska rörelse, inte färg, så en färgtoning godkänns och en
övergång på rörelse gör det inte. Rörelse uttrycks också som en övergång snarare än som en
keyframe-animation, eftersom den förra är trivial att avbryta och den senare inte är det. Som sidan
uttrycker det: en regel som förlorar på specificitet fallerar i tysthet.

Rullningsstyrd rörelse har ett eget felläge. Bland de
[11 tillgänglighetsbrister som webbläsaren rapporterade som felfria](/sv/portfolio/fixed-11-accessibility-defects-the-browser-called-healthy-131/)
fanns en rullningsstyrd animation, inaktiv på en sida som var för kort för att rullas, som
permanent hade skurit bort sidfoten på tre sidor. Webbplatsen klarade sina automatiska
tillgänglighetsregler ändå, eftersom felet låg i hur sidan renderades och inte i vad uppmärkningen
sade.

En linter kan göra kontrollen omöjlig att hoppa över. Ett
[designsystem med fyrtioåtta tokens](/sv/portfolio/built-a-48-token-design-system-160/), byggt på
plattformens eget glasmaterial, har rörelse som en av sina sex grupper av tokens, och dess
lintverktyg avvisar en animation som deklareras utan att respektera inställningen för minskad
rörelse. Sidan anger skälet: en animation läggs till i ett ögonblick av finputsning, kontrollen av
inställningen är den del som hoppas över, och därför gör regeln det omöjligt att skriva animationen
utan den.

Den här webbplatsens stilmallar visar samma vanor på andra ställen. De två kugghjulen i sidhuvudet
snurrar ett varv på 60 respektive 96 sekunder, och båda får `animation: none` under `reduce`. Deras
rullningskopplade parallax är spärrad två gånger, inuti `prefers-reduced-motion: no-preference` och
inuti ett `@supports`-test för `animation-timeline: scroll()`. I en webbläsare som saknar
funktionen står kugghjulen kvar där de är, och kommentaren i koden kallar den reservlösningen för
själva designen. I sidfoten får rutan med upphovsrätten sitt dolda läge från animationens
bakåtfyllnad (`backwards`) i stället för från en deklarerad `opacity: 0`. Kommentaren förklarar
varför: en inaktiv tidslinje tillämpar ingenting alls, och den gamla `opacity: 0` hade dolt
upphovsrätten på varje kort sida.

## Var det går fel

- **Avstängningen förlorar kaskaden.** En generell `transition: none` på den universella selektorn
  har nästan ingen specificitet, så varje regel med en klass fortsätter att röra sig, och ingenting
  rapporterar det. Ett block som placeras efter reglerna det måste slå, och som namnger de rörliga
  selektorerna, låter det stilla läget vinna.
- **Inställningen läggs till senare, eller aldrig.** En animation i grundstilen rör sig för alla
  tills någon kommer ihåg att stänga av den. Den som deklarerar animationen inuti
  `@media (prefers-reduced-motion: no-preference)` gör stillhet till standardläget.
- **En rullningstidslinje möter en sida där det inte finns något att rulla.** Tidslinjen är inaktiv
  och animationen gör ingenting, så ett startläge som skrivits in i grundstilen, t.ex. en
  `opacity: 0` som väntar på att animeras bort, ligger kvar. Ett startläge som kommer från
  bakåtfyllnaden försvinner tillsammans med animationen.
- **Ett värde som webbläsaren avvisar i en nyckelbild faller bort i tysthet.** Specifikationen
  säger att en egenskap som anges men är ogiltig i en nyckelbild animeras som om den nyckelbilden
  inte fanns. Ett felstavat värde hoppar över ett steg utan något felmeddelande.
- **En dekorativ loop snurrar utan något sätt att stoppa den.** En `infinite`-animation som startar
  när sidan laddas, bredvid texten, faller under 2.2.2 så fort den passerar fem sekunder. En
  pausknapp, eller ett slut inom fem sekunder, uppfyller kriteriet.
- **”Minska” läses som ”ta bort allt”.** Den som stryker varje tillståndsändring kan ta bort
  information tillsammans med rörelsen. Att visa det nya läget direkt, eller med en toning, behåller
  informationen och tar bort rörelsen.

## Läs mer

- [CSS Animations Level 1](https://www.w3.org/TR/css-animations-1/) — regeln `@keyframes`,
  animationsegenskaperna, fyllnadslägena och de händelser som en animation skickar.
- [CSS Transitions Level 1](https://www.w3.org/TR/css-transitions-1/) — hur en ändring av ett
  egenskapsvärde sprids ut över en tid i stället för att tillämpas direkt.
- [Scroll-driven Animations](https://www.w3.org/TR/scroll-animations-1/) — tidslinjer för
  rullningsförlopp, notationen `scroll()` och fallen där en tidslinje är inaktiv.
- [Media Queries Level 5: prefers-reduced-motion](https://www.w3.org/TR/mediaqueries-5/#prefers-reduced-motion)
  — de två värdena och vad en läsare som väljer `reduce` ber om.
- [Understanding SC 2.2.2: Pause, Stop, Hide](https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html)
  — gränsen på fem sekunder, vad som räknas som automatisk start och vilka sätt att pausa som duger.
- [Understanding SC 2.3.3: Animation from Interactions](https://www.w3.org/WAI/WCAG22/Understanding/animation-from-interactions.html)
  — vestibulära reaktioner, parallax och inställningen för minskad rörelse som ett sätt att
  uppfylla kriteriet.

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