# Kontrastforhold

## Hva det er

Et kontrastforhold er det ene tallet, fra 1:1 til 21:1, som WCAG bruker for å vurdere om tekst,
ikoner og de andre synlige delene av en side skiller seg ut fra det som ligger bak dem. Det
sammenligner luminansen til to farger, så det måler en forskjell i lyshet og ser helt bort fra
fargetone. Designere sier ofte fargekontrast eller luminanskontrast, og revisjoner lister
kontrastforhold per fargepar. Alle disse navnene viser til den samme beregningen.

Formelen er kort. Ta den relative luminansen til den lyseste fargen, L1, og til den mørkeste, L2,
og del (L1 + 0,05) på (L2 + 0,05). Relativ luminans er normalisert til 0 for den mørkeste svarte og
1 for den lyseste hvite. For en sRGB-farge blir hver kanal først regnet om fra sin gammakodede
verdi til lineært lys, og de tre vektes så: 0,2126 for rødt, 0,7152 for grønt og 0,0722 for blått.
To like farger gir 1:1, og svart på hvitt gir 21:1.

Det er i de vektene intuisjonen svikter. Ren grønn på svart måler omtrent 15,3:1, mens ren blå på
svart så vidt når omtrent 2,4:1, selv om begge ser like klare ut. Ren rød på hvitt havner på
3,998:1. Mellomgrått `#767676` på hvitt måler 4,54:1, og `#777777`, ett trinn lysere, måler 4,48:1.
Regnestykket får plass på et dusin linjer:

```js
// Contrast ratio of two sRGB colours, as WCAG 2.2 defines it
const linear = (c) => {
    const s = c / 255;
    return s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
};
const luminance = (rgb) => {
    const [r, g, b] = rgb.map(linear);
    return 0.2126 * r + 0.7152 * g + 0.0722 * b;
};
const contrast = (a, b) => {
    const [hi, lo] = [luminance(a), luminance(b)].sort((x, y) => y - x);
    return (hi + 0.05) / (lo + 0.05);
};
contrast([118, 118, 118], [255, 255, 255]); // 4.54...
```

I WCAG 2.2 er forholdet en definisjon, og fire suksesskriterier setter terskler for det:

- **1.4.3 Kontrast (minimum), nivå AA:** minst 4,5:1 for tekst og bilder av tekst, og minst 3:1 for
  stor tekst. Tekst i en inaktiv kontroll, ren dekorasjon og logoer har ikke noe kontrastkrav.
- **1.4.6 Kontrast (forbedret), nivå AAA:** minst 7:1, og 4,5:1 for stor tekst.
- **1.4.11 Kontrast for ikke-tekstlig innhold, nivå AA:** minst 3:1 mot fargene ved siden av for
  alt som identifiserer en kontroll og tilstanden dens, og for de delene av en grafikk som trengs
  for å forstå den.
- **2.4.13 Fokusutseende, nivå AAA:** et område av fokusindikatoren som er minst like stort som en
  omkrets på 2 CSS-piksler rundt kontrollen, endrer seg med minst 3:1 mellom tilstanden med fokus
  og tilstanden uten.

Stor tekst betyr minst 18 punkter, eller 14 punkter i fet skrift. I CSS-piksler er det 24 px, eller
omtrent 18,7 px i fet skrift.

## Hvorfor det er viktig

Tersklene kommer fra målt synstap, og det hjelper å kjenne opprinnelsen når noen vil bøye dem.
Forklaringsdokumentet til WCAG, Understanding WCAG 2.2, tar utgangspunkt i 3:1, minimumet en
ANSI-standard satte for observatører med vanlig syn. Synsstyrke på 20/40 følges av et tap i
kontrastfølsomhet på omtrent 1,5, så 3 × 1,5 gir 4,5:1, og det samme dokumentet påpeker at 20/40
ofte oppgis som vanlig synsskarphet ved rundt 80 års alder. AAA-tallet på 7:1 kompenserer for syn
rundt 20/80. Fordi forholdet bare bruker luminans, holder det seg på tvers av de fleste typer
fargesynsavvik, noe regler basert på fargetone ikke ville gjort. Den samme marginen hjelper alle
som leser på en telefon i skarpt sollys.

Beslutningen et kontrastforhold avgjør, er altså hvilke farger en merkevare kan bruke til hvilken
jobb, og den beslutningen er langt billigere i paletten enn på siden. En merkevarefarge som måler
3,2:1 mot hvitt, har fortsatt oppgaver: store overskrifter, ikoner og omrisset av et skjemafelt,
som trenger 3:1, bakgrunner bak mørk tekst, dekorasjon og selve logoen. Det den ikke kan bære, er
brødtekst, lenketekst i et avsnitt eller plassholdertekst, som alle trenger 4,5:1. Å avgjøre det én
gang, i designtokenene, koster en ettermiddag. Å oppdage det etter lansering betyr å fargelegge om
hver komponent som lånte fargen, og et mørkt tema dobler antallet par som må sjekkes.

Kontrast er også ett av få WCAG-krav en maskin kan verifisere nøyaktig, forutsatt at den kjenner
begge fargene. Derfor er det det første funnet i de fleste automatiserte revisjoner og det første
spørsmålet på mange sjekklister for innkjøp, og nivå AA er det nivået regler og kontrakter om
universell utforming oftest nevner. I Norge står 1.4.3 blant WCAG-kravene i regelverket for
universell utforming av ikt, og Uu-tilsynet oppgir at kravet gjelder for både offentlig og privat
sektor. Å strekke seg etter AAA-nivåets 7:1 overalt er et valg som må veies: WCAG fraråder selv å
kreve AAA som policy for hele nettsteder, men 7:1 er et fornuftig mål for lang lesetekst der
paletten tillater det.

## Slik ser det ut i praksis

To sider på dette nettstedet viser forholdet holdt som et registrert tall og ikke som et skjønn på
øyemål.

Da nettstedets fargesystem ble lukket,
[ble hver av de 28 fargene dokumentert med kontrastforholdet den måler](/nb/portfolio/closed-the-colour-system-at-28-colours-133/)
på flaten den står på, og elleve merkevareverdier ble deklarert én gang som tokens. En linter
feiler på fem måter, og én av dem er en farge registrert med feil kontrastforhold. Den faste
regelen sier blant annet at et dokumentert kontrastforhold aldri skal senkes for å få et design til
å fungere, og et forslag om en tjueniende farge må ta med kontrastforholdet. Den samme siden setter
en terskel nummer to, en perseptuell avstand på 0,02 i et uniformt fargerom, som avgjør når to
skrivemåter egentlig er én farge. Det tallet skiller oppføringene i paletten fra hverandre og er et
annet mål enn kontrast.

Det vanskeligere tilfellet var tekst over et fotografi. Siden om
[hvordan hele nettstedet ble løftet til WCAG 2.2 nivå AA](/nb/portfolio/took-wcag-2-2-level-aa-across-the-whole-site-130/)
viser at en automatisert regelmotor rapporterer slik kontrast som umulig å vurdere, og at
nettstedet hadde forsvart den med et argument i stedet for et tall. Målt var 49 av 64 par av side
og tema under AA, og to flater designet aldri hadde tatt eierskap til, viste seg å være årsaken.
Sjekken som fant dem, er nå et minstekrav: hvert par må holde AA over veggen byggingen tegner, og et
par som faller under, får byggingen til å feile.

## Hvor det går galt

**Tekst over et fotografi består i verktøyet og stryker på skjermen.** WCAG måler tekst mot den
angitte bakgrunnen og antar hvitt når ingen er satt. En overskrift på et toppbilde har en deklarert
bakgrunn som ikke er den som ligger under bokstavene, så et kontrollverktøy måler enten feil par
eller gir elementet tilbake til manuell vurdering. Mål mot de lyseste og mørkeste pikslene teksten
kan havne på ved hver beskjæring og bredde, eller legg teksten på en ensfarget bakgrunn eller et
dempende lag med kjent farge. Uu-tilsynet sier det samme om graderte farger i bakgrunn eller
tekst: punktet med den svakeste kontrastverdien er det som gjelder.

**Et token måler 4,6:1, og siden viser 3,9:1.** Opasitet, tekst i `rgba()`, et gjennomsiktig
overlegg eller en blandingsmodus endrer fargen som når skjermen, så forholdet som er registrert for
tokenet, beskriver en farge ingen ser. Regn ut forholdet for paret slik det faktisk blir satt
sammen, eller hold alfa borte fra tekst helt.

**En revisjon melder 4,49:1 som bestått.** Et forhold vist med én desimal gjør 4,49 om til 4,5.
Forklaringsdokumentet sier uttrykkelig at tersklene ikke rundes av: 4,499:1 oppfyller ikke 4,5:1.
Lagre minst to desimaler, og sammenlign den rå verdien med terskelen.

**Det lyse temaet sjekkes, og det mørke leveres på tillit.** Hvert tema, og hver tilstand en farge
kan ha, er sitt eget par: hover, fokus, besøkt, feil og plassholdertekst, som regnes som tekst og
trenger 4,5:1. En deaktivert kontroll er unntatt. Uu-tilsynet skriver at tilsynet vanligvis tester
tekst i standardtilstanden, men at også de andre tilstandene er dekket av kravet. Lag listen over
par ut fra tokenene, per tema og per tilstand, og sjekk listen i stedet for et skjermbilde.

**Tynn skrift består på papiret og blekner på skjermen.** Forholdet kommer fra de angitte fargene,
men kantutjevning tegner hårfine snitt svakere enn CSS-fargen deres, og forklaringsdokumentet
nevner nettopp dette tilfellet: slik tekst kan bestå nominelt og likevel leses med mye lavere
kontrast. Øk forholdet for lette snitt, eller velg et tyngre snitt av skrifttypen.

## Les mer

- [WCAG 2.2: contrast ratio](https://www.w3.org/TR/WCAG22/#dfn-contrast-ratio) — den normative
  definisjonen, med merknadene om bakgrunnsfarge, hvitt som standard og kantutjevning.
- [Understanding SC 1.4.3 Contrast (Minimum)](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html)
  — hvor 4,5:1 og 3:1 kommer fra, hvordan stor tekst måles, og hvorfor forholdene ikke rundes av.
- [Understanding SC 1.4.11 Non-text Contrast](https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html)
  — 3:1-regelen for kontroller, tilstandene deres og meningsbærende grafikk, med eksempler som
  består og stryker.
- [Understanding SC 1.4.6 Contrast (Enhanced)](https://www.w3.org/WAI/WCAG22/Understanding/contrast-enhanced.html)
  — AAA-nivået på 7:1 og leserne det er ment for.
- [CSS Color Module Level 4](https://www.w3.org/TR/css-color-4/) — overføringsfunksjonen for sRGB og
  fargerommene luminansformelen forutsetter.
- [1.4.3 Kontrast (minimum) (Nivå AA)](https://www.uutilsynet.no/wcag-standarden/143-kontrast-minimum-niva-aa/95)
  — Uu-tilsynets tolking av kravet i det norske regelverket: sektorene det gjelder for, graderte
  farger og tilstandene tilsynet tester.

<https://engineer.company/nb/glossary/contrast-ratio/>
