# Kontrastförhållande

## Vad det är

Ett kontrastförhållande är det enda tal, från 1:1 till 21:1, som WCAG använder
för att bedöma om text, ikoner och sidans andra synliga delar sticker ut från
det som ligger bakom dem. Det jämför luminansen hos två färger, så det mäter en
skillnad i ljushet och bortser helt från kulören. Formgivare säger ofta
färgkontrast eller luminanskontrast, på engelska heter det contrast ratio, och
granskningar listar kontrastförhållanden per färgpar; alla namnen avser samma
beräkning.

Formeln är kort. Ta den relativa luminansen för den ljusare färgen, L1, och för
den mörkare, L2, och dividera (L1 + 0,05) med (L2 + 0,05). Relativ luminans är
normaliserad till 0 för det mörkaste svarta och 1 för det ljusaste vita. För en
sRGB-färg omvandlas först varje kanal från sitt gammakodade värde till linjärt
ljus, och sedan viktas de tre: 0,2126 för rött, 0,7152 för grönt och 0,0722 för
blått. Två identiska färger ger 1:1, och svart på vitt ger 21:1.

Det är vikterna som lurar intuitionen. Ren grön på svart mäter ungefär 15,3:1,
medan ren blå på svart bara når ungefär 2,4:1, trots att båda ser lika klara ut.
Ren röd på vitt landar på 3,998:1. Mellangrått `#767676` på vitt mäter 4,54:1,
och `#777777`, ett steg ljusare, mäter 4,48:1. Aritmetiken ryms på ett dussin
rader:

```js
// Kontrastförhållandet mellan två sRGB-färger enligt WCAG 2.2
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 är förhållandet en definition, och fyra framgångskriterier sätter
gränsvärden för det:

- **1.4.3 Kontrast (minimum), nivå AA:** minst 4,5:1 för text och textbilder,
  och minst 3:1 för stor text. Text i en inaktiv komponent i gränssnittet, ren
  dekoration och logotyper har inget kontrastkrav.
- **1.4.6 Kontrast (förbättrad), nivå AAA:** minst 7:1, och 4,5:1 för stor text.
- **1.4.11 Kontrast för icke-textinnehåll, nivå AA:** minst 3:1 mot angränsande
  färger för det som identifierar en komponent och dess tillstånd, och för de
  delar av en grafik som behövs för att förstå den.
- **2.4.13 Fokusutseende, nivå AAA:** en yta av fokusindikatorn som är minst
  lika stor som en omkrets runt komponenten med en tjocklek på 2 CSS-pixlar
  ändras med minst 3:1 mellan fokuserat och ofokuserat tillstånd.

Stor text betyder minst 18 punkter, eller 14 punkter i fetstil. I CSS-pixlar
blir det 24 px, eller ungefär 18,7 px i fetstil.

## Varför det spelar roll

Gränsvärdena kommer från uppmätt synnedsättning, och den som känner till
ursprunget har lättare att stå emot när någon vill tumma på dem. WCAG:s
Understanding-dokument utgår från 3:1, den lägsta nivå som en ANSI-standard
satte för betraktare med normal syn. En synskärpa på 20/40, i svensk notation
visus 0,5, följer med en förlust i kontrastkänslighet på ungefär 1,5, så 3 × 1,5
ger 4,5:1, och samma dokument noterar att 20/40 ofta anges som typisk synskärpa
vid ungefär 80 års ålder. AAA-nivåns 7:1 kompenserar för en synskärpa runt
20/80. Eftersom förhållandet bara bygger på luminans håller det för de flesta
former av färgseendedefekter, vilket regler som bygger på kulör inte skulle
göra. Samma marginal hjälper alla som läser på en mobil i starkt solljus.

Beslutet som ett kontrastförhållande avgör är alltså vilka färger ett varumärke
får använda till vilket jobb, och det beslutet är mycket billigare att fatta i
paletten än på sidan. En varumärkesfärg som mäter 3,2:1 mot vitt har fortfarande
gott om arbete: stora rubriker, ikoner och kanten på ett formulärfält, som
behöver 3:1, bakgrunder bakom mörk text, dekoration och själva logotypen. Det
den inte får bära är brödtext, länktext i ett stycke eller platshållartext, som
alla behöver 4,5:1. Att bestämma det en gång, i designtokens, tar en
eftermiddag. Att upptäcka det efter lanseringen innebär att färga om varje
komponent som har lånat färgen, och ett mörkt tema fördubblar antalet par att
kontrollera.

Kontrast är också ett av de få krav i WCAG som en maskin kan kontrollera exakt,
förutsatt att den känner till båda färgerna. Det gör kontrast till det första
fyndet i de flesta automatiserade granskningar och till den första frågan på
många checklistor vid upphandling, och nivå AA är den nivå som regler och avtal
om tillgänglighet oftast anger. Att sträcka sig efter AAA-nivåns 7:1 överallt är
ett val att väga: WCAG avråder självt från att kräva AAA som policy för hela
webbplatser, men 7:1 är ett sunt mål för lång brödtext där paletten tillåter
det.

## Så ser det ut i praktiken

Två sidor på den här webbplatsen visar förhållandet hållet som ett registrerat
tal snarare än en bedömning med ögat.

När webbplatsens färgsystem slöts
[dokumenterades var och en av dess 28 färger med det kontrastförhållande den uppmäts till](/sv/portfolio/closed-the-colour-system-at-28-colours-133/)
på den yta där den förekommer, och elva varumärkesvärden deklarerades en gång
som tokens. En linter fäller på fem sätt, och ett av dem är en färg som har
registrerats med fel förhållande. Den stående regeln innebär bl.a. att ett
dokumenterat förhållande aldrig sänks för att få en design att fungera, och
argumentet för en tjugonionde färg måste innehålla dess förhållande. Samma sida
sätter ett andra gränsvärde, ett perceptuellt avstånd på 0,02 i en likformig
färgrymd, som avgör när två stavningar egentligen är en och samma färg. Det
talet skiljer palettens poster åt; det är ett annat mått än kontrast.

Det svårare fallet var text över ett fotografi. Sidan om
[hur hela webbplatsen fördes upp till WCAG 2.2 på nivå AA](/sv/portfolio/took-wcag-2-2-level-aa-across-the-whole-site-130/)
noterar att en automatiserad regelmotor rapporterar sådan kontrast som omöjlig
att utvärdera, och att webbplatsen hade försvarat den med ett argument snarare
än en siffra. Uppmätt låg 49 av 64 par av sida och tema under AA, och två ytor
som designen aldrig hade haft kontroll över visade sig vara orsaken. Kontrollen
som hittade dem är nu en lägstanivå: varje par måste klara AA över väggen som
bygget ritar, och ett par som inte når dit får bygget att stoppa.

## Var det går fel

**Text över ett fotografi klarar sig i verktyget men faller på skärmen.** WCAG
mäter text mot dess angivna bakgrund och antar vitt när ingen är satt. En rubrik
på en hero-bild har en deklarerad bakgrund som inte är den som ligger under
bokstäverna, så ett kontrollverktyg mäter antingen fel par eller lämnar tillbaka
elementet för manuell granskning. Mät mot de ljusaste och mörkaste pixlarna som
texten kan hamna på vid varje beskärning och bredd, eller ge texten en
heltäckande eller tonad bakgrund vars färg är känd.

**En token mäter 4,6:1 och sidan visar 3,9:1.** Opacitet, text i `rgba()`, ett
genomskinligt överlägg eller ett blandningsläge ändrar färgen som når skärmen,
så förhållandet som har registrerats för en token beskriver en färg som ingen
ser. Beräkna förhållandet för det sammansatta paret, eller håll alfakanalen
borta från text helt och hållet.

**En granskning rapporterar 4,49:1 som godkänt.** Ett förhållande som visas med
en decimal gör 4,49 till 4,5. Understanding-dokumentet säger uttryckligen att
gränsvärdena inte avrundas: 4,499:1 uppfyller inte 4,5:1. Spara minst två
decimaler och jämför det oavrundade värdet med gränsvärdet.

**Det ljusa temat kontrolleras och det mörka levereras på förtroende.** Varje
tema, och varje tillstånd som en färg kan anta, är ett eget par: hovring, fokus,
besökt länk, felmeddelande och platshållartext, som räknas som text och behöver
4,5:1. En inaktiverad komponent är undantagen. Generera listan över par ur dina
tokens, per tema och per tillstånd, och kontrollera listan i stället för en
skärmbild.

**Tunn typografi klarar sig på papperet och bleknar på skärmen.** Förhållandet
räknas fram ur de angivna färgerna, men kantutjämningen ritar hårfina snitt
blekare än deras färg i CSS, och Understanding-dokumentet nämner just det
fallet: sådan text kan klara kravet på papperet och ändå läsas med betydligt
lägre kontrast. Höj förhållandet för tunna snitt, eller välj ett kraftigare
snitt av typsnittet.

## Läs mer

- [WCAG 2.2: contrast ratio](https://www.w3.org/TR/WCAG22/#dfn-contrast-ratio) —
  den normativa definitionen, med anmärkningarna om bakgrundsfärg, vitt som
  standard och kantutjämning.
- [Understanding SC 1.4.3 Contrast (Minimum)](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html)
  — var 4,5:1 och 3:1 kommer ifrån, hur stor text mäts och varför förhållandena
  inte avrundas.
- [Understanding SC 1.4.11 Non-text Contrast](https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html)
  — regeln om 3:1 för komponenter, deras tillstånd och meningsbärande grafik,
  med exempel som klarar och inte klarar kravet.
- [Understanding SC 1.4.6 Contrast (Enhanced)](https://www.w3.org/WAI/WCAG22/Understanding/contrast-enhanced.html)
  — AAA-nivån på 7:1 och de läsare den är avsedd för.
- [CSS Color Module Level 4](https://www.w3.org/TR/css-color-4/) —
  överföringsfunktionen för sRGB och de färgrymder som luminansformeln
  förutsätter.
- [Digital tillgänglighet](https://www.digg.se/kunskap-och-stod/digital-tillganglighet)
  — Diggs sida om lagen om tillgänglighet till digital offentlig service, som
  hänvisar offentliga aktörer till standarden EN 301 549 och därmed till WCAG
  2.1.

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