Dla programistów
Kontrast tekstu według WCAG: jak sprawdzić i poprawić kolory
Szary tekst na białym tle, biały napis na średnio jasnym przycisku i tekst na zdjęciu to miejsca, w których łatwo o zbyt niski kontrast. Poradnik pokazuje progi WCAG, sposób pomiaru i poprawkę, która zostawia kolor w tym samym odcieniu.
- Redakcja HNarzędzi
- Publikacja:
Tekst, który na dobrym monitorze wygląda dobrze, bywa trudny do odczytania na telefonie w słońcu albo dla osoby ze słabszym wzrokiem. WCAG nie zostawia tej oceny na oko: kontrast tekstu z tłem liczy się wzorem i porównuje z progiem. Wystarczy więc znać dwa kolory, żeby wiedzieć, czy para je spełnia, a jeśli nie, jak bardzo trzeba zmienić jasność.
Progi WCAG 2.x
Wartości poniżej pochodzą z WCAG 2.2 (zalecenie W3C z 12 grudnia 2024) i opisów kryteriów 1.4.3 oraz 1.4.11. Sprawdziliśmy je w październiku 2026.
| Co sprawdzasz | AA | AAA | Kryterium |
|---|---|---|---|
| Zwykły tekst | 4,5:1 | 7:1 | 1.4.3 (AA), 1.4.6 (AAA) |
| Duży tekst | 3:1 | 4,5:1 | 1.4.3 (AA), 1.4.6 (AAA) |
| Elementy interfejsu i ważne części grafik, np. obramowanie pola, ikona, stan fokusu | 3:1 względem sąsiednich kolorów | brak progu | 1.4.11 |
Współczynnik kontrastu nie podlega zaokrągleniu. W3C podaje przykład: 4,499:1 nie spełnia progu 4,5:1. Narzędzie Kontrast kolorów pokazuje taki wynik jako 4,49:1, żeby nie sugerować zgodności.
Progu dla tekstu nie stosuje się do tekstu w nieaktywnych elementach interfejsu, do czystej dekoracji, do tekstu niewidocznego dla nikogo i do logotypów. Kryterium 1.4.11 pomija nieaktywne komponenty. Domyślny wygląd fokusu, który nadaje przeglądarka, W3C również wyłącza z wymagania, ale własny wskaźnik fokusu musi mieć 3:1.
Co to jest duży tekst
WCAG definiuje duży tekst jako co najmniej 18 punktów albo 14 punktów pogrubiony. Strona W3C o kryterium 1.4.3 przelicza to na około 24 px i około 18,5 px (przy 1 pt = 1,333 px). Ta sama strona zaznacza, że „18 punktów” i „pogrubienie” mogą znaczyć co innego w różnych krojach pisma, a bardzo cienkie kroje są trudniejsze do odczytania przy niskim kontraście. Gdy tekst jest na granicy, traktuj go jak zwykły.
Jak liczy się kontrast
Kontrast to (L1 + 0,05) / (L2 + 0,05), gdzie L1 to luminancja względna jaśniejszego koloru, a L2 ciemniejszego. Luminancję W3C definiuje jako 0,2126·R + 0,7152·G + 0,0722·B z kanałów sRGB po linearyzacji. Dla szarego #777777 kanał 119/255 daje po linearyzacji 0,1845, więc kontrast na białym wynosi (1 + 0,05) / (0,1845 + 0,05) = 4,478:1. Nie musisz tego liczyć ręcznie, ale warto wiedzieć, skąd bierze się wynik: zielony wnosi do jasności najwięcej, niebieski najmniej, więc dwa kolory o podobnej „jasności na oko” mogą mieć różny kontrast.
Skąd wziąć kolory do sprawdzenia
- Z kodu lub projektu. Kontrast kolorów przyjmuje HEX,
rgb(),hsl()ioklch(). Przezroczysty kolor tekstu narzędzie najpierw nakłada na tło, a przezroczyste tło na biel. - Ze zrzutu ekranu, makiety lub zdjęcia. W narzędziu Pipeta kolorów ze zdjęcia wczytujesz obraz i klikasz piksel. Narzędzie podaje HEX, RGB i HSL. Na Chrome i Edge działa też pipeta, która pobiera kolor z dowolnego miejsca na ekranie. Kolor ze zrzutu może się nieco różnić od wartości w CSS, np. po kompresji do JPG, więc gdy masz dostęp do kodu, bierz kolor stamtąd.
- Z innego zapisu. Konwerter kolorów zamienia HEX, RGB, HSL, HSV, CMYK i OKLCH. Ma też własny blok kontrastu wobec wybranego tła, ale pełną tabelę AA i AAA oraz propozycje poprawek znajdziesz w Kontraście kolorów.
Przykład: kilka par kolorów policzonych dwa razy
Każdą parę wpisaliśmy w narzędzie Kontrast kolorów w Chromium (wersja PL i EN dały te same liczby), a potem przeliczyliśmy niezależnie w Node wzorem z definicji W3C.
| Tekst | Tło | Narzędzie | Wzór w Node | Wniosek |
|---|---|---|---|---|
#777777 |
#FFFFFF |
4,48:1 | 4,4781 | nie spełnia AA dla zwykłego tekstu, spełnia dla dużego |
#767676 |
#FFFFFF |
4,54:1 | 4,5422 | spełnia AA |
#595959 |
#FFFFFF |
7,00:1 | 7,0047 | spełnia AAA |
#999999 |
#FFFFFF |
2,85:1 | 2,8490 | nie spełnia nawet progu dla dużego tekstu |
#FFFFFF |
#4A90E2 |
3,29:1 | 3,2922 | tylko duży tekst i elementy interfejsu |
#FFFFFF |
#3278C9 |
4,50:1 | 4,5010 | spełnia AA |
#DDDDDD |
#FFFFFF |
1,36:1 | 1,3582 | ramka pola nie spełnia 3:1 |
Różnica między #777777 a #767676 to jeden poziom w każdym kanale, a jedna z tych par przechodzi AA, druga nie. Stąd brak zaokrąglania: wynik 4,48:1 wygląda na „prawie 4,5”, ale próg jest progiem. Ramka #DDDDDD ma znaczenie tylko wtedy, gdy to ona pokazuje, że w tym miejscu jest pole formularza. Jeśli pole odróżnia od tła coś innego, kryterium 1.4.11 jej nie dotyczy.
Jak poprawić kolor bez zmiany charakteru
Kontrast zależy od jasności obu kolorów. Odcień możesz więc zostawić i zmienić tylko jasność jednego z nich. Narzędzie Kontrast kolorów robi to w przestrzeni OKLCH: szuka najbliższej jasności, która osiąga wybrany cel (AA 4,5:1, AAA 7:1 albo 3:1), i proponuje zarówno zmianę koloru tekstu, jak i tła.

Dla białego tekstu na #4A90E2 narzędzie proponuje dwie drogi. Tło #3278C9 daje 4,50:1. Tekst zmieniony na #272727 daje 4,54:1, ale przycisk przestaje wtedy mieć biały napis. Zmieniaj ten element, który mniej wpływa na wygląd marki. Jeśli firmowym kolorem jest #4A90E2, a napis ma zostać biały, pozostaje duży tekst: od 24 px (albo 18,5 px pogrubionego) wystarcza 3:1, a ta para ma 3,29:1.
Konwerter kolorów pokazuje, co dokładnie się zmieniło:
| Kolor | HEX | HSL | OKLCH |
|---|---|---|---|
| przed | #4A90E2 |
hsl(212, 72%, 59%) | oklch(64,6% 0,142 253,9) |
| po | #3278C9 |
hsl(212, 60%, 49%) | oklch(56,9% 0,143 254,3) |
Barwa i nasycenie w OKLCH prawie się nie zmieniły, jasność spadła z 64,6% do 56,9%. W HSL zmieniło się też nasycenie (72% na 60%), bo ta przestrzeń inaczej opisuje jasność, więc nie porównuj kolorów po samych liczbach HSL. Ciemniejsze odcienie z konwertera powstają przez mieszanie z czernią w sRGB. To szybka paleta do przeglądu, ale każdy wybrany odcień sprawdź w Kontraście kolorów.
Dla AAA (7:1) szarość na białym tle musi być jeszcze ciemniejsza: #595959 ma 7,00:1.
Tekst na zdjęciu lub gradiencie
Narzędzie porównuje dwa kolory, a tło ze zdjęciem lub gradientem ma ich tysiące. Skoro W3C każe mierzyć kontrast względem tła, na którym tekst faktycznie się wyświetla, sprawdź najgorsze miejsce: dla jasnego tekstu najjaśniejszy fragment tła pod napisem, dla ciemnego najciemniejszy.
Do przykładu użyliśmy syntetycznego banera 800×300 px z poziomym gradientem od #1F4E8C do #9CC3F5, bez zdjęcia i szumu. Pobraliśmy kolory z trzech miejsc i sprawdziliśmy z nimi biały tekst:
| Miejsce na banerze | Kolor tła | Biały tekst |
|---|---|---|
| 10% szerokości | #2C5A97 |
6,96:1 |
| 55% szerokości | #648EC6 |
3,37:1 |
| 90% szerokości | #90B7EB |
2,07:1 |
| skrajny prawy piksel | #9CC3F5 |
1,82:1 |

Ten sam napis jest czytelny po lewej stronie i nie spełnia nawet progu dla dużego tekstu po prawej. Paleta „Dominujące kolory” w pipecie nie wystarczy do takiej oceny: to średnie z grup pikseli, więc najjaśniejszy kolor z palety przy domyślnych sześciu kolorach (#94BCEE) jest ciemniejszy od skrajnego piksela (#9CC3F5).
Najprostsza poprawka to półprzezroczysta czarna nakładka pod tekstem. Czarny o danej przezroczystości przyciemnia każdy kanał o ten sam odsetek, więc kolor po nałożeniu policzysz z góry. Dla #90B7EB wyszło tak:
| Nakładka | Kolor po nałożeniu | Biały tekst |
|---|---|---|
| 20% | #7392BC |
3,20:1 |
| 30% | #6580A5 |
4,05:1 |
| 40% | #566E8D |
5,24:1 |
| 50% | #485C76 |
6,84:1 |
Przy 30% biały tekst spełnia próg dla dużego (3:1), ale nie dla zwykłego, a dopiero 40% daje AA. Policzone kolory wpisaliśmy do narzędzia i zgadzają się z tabelą. Ten wynik dotyczy najjaśniejszego punktu, więc ciemniejsze części banera mają kontrast jeszcze wyższy. Przy prawdziwym zdjęciu pojedynczy piksel może trafić w plamę światła, więc kliknij kilka miejsc pod tekstem.
Elementy interfejsu
Kryterium 1.4.11 wymaga 3:1 względem sąsiednich kolorów dla części interfejsu potrzebnych do rozpoznania komponentu i jego stanu: obramowania pola, ikony, wskaźnika fokusu. Dotyczy też części wykresów, bez których nie da się zrozumieć danych. Tekst na obrazku trzeba natomiast spełnić według 1.4.3, a nie 3:1. Sprawdź także stany: hover, fokus i zaznaczenie mają własne kolory, a w narzędziu wpisuje się je osobno.
APCA: model w rozwoju, nie wymóg
APCA to inny algorytm kontrastu, zależny od polaryzacji (ciemny tekst na jasnym i odwrotnie) i od rozmiaru oraz grubości liter. Twórcy opisują go jako kandydata na metodę dla WCAG 3 (APCA in a Nutshell, apca-w3, sprawdzone w październiku 2026). Sam WCAG 3 jest roboczym szkicem W3C z 10 września 2026 r., a według szkicu algorytm kontrastu nie jest jeszcze ustalony (WCAG 3.0).
Wynik APCA to wartość Lc, a zalecane minima zależą od zastosowania: według dokumentacji Lc 90 jest preferowane dla tekstu ciągłego, Lc 75 to minimum dla kolumn tekstu, Lc 60 dla tekstu treści, Lc 45 dla nagłówków, a Lc 30 i Lc 15 dla elementów pobocznych. Narzędzie pokazuje Lc informacyjnie. Obie metody oceniają pary inaczej. #777777 na białym nie spełnia AA (4,48:1), a w APCA ma Lc 71,1, czyli więcej niż minimum dla tekstu treści, ale mniej niż dla kolumn tekstu. Biały na #3278C9 ma 4,50:1 i Lc -76,4 (minus oznacza jasny tekst na ciemnym tle). Zgodność z WCAG 2.x oceniaj progami WCAG 2.x, a wynik APCA traktuj jako dodatkową wskazówkę.
Polskie wymagania
Według serwisu gov.pl o dostępności cyfrowej dostępność cyfrowa jest obowiązkiem prawnym podmiotów publicznych. Strona o wymogach dla podmiotów publicznych mówi, że wymagania ustawy odpowiadają wytycznym WCAG na poziomie AA, z niewielkimi ograniczeniami. Dla usług handlu elektronicznego gov.pl wymienia normę EN 301 549 w wersji V3.2.1 z 2021 roku i wspomina o jej aktualizacji (sprawdzone w październiku 2026). Żadna z tych stron nie podaje progów kontrastu, więc liczby bierz z WCAG. To nie jest porada prawna: czy i jakie obowiązki ma Twoja organizacja, ustal na podstawie przepisów lub z prawnikiem.
Kiedy sprawdzenie kolorów nie wystarczy
Kontrast kolorów porównuje dwa kolory, więc nie oceni gradientu, zdjęcia ani tekstu pod półprzezroczystą warstwą, dopóki sam nie wskażesz konkretnych kolorów. Nie sprawdza grubości kroju ani rozmiaru tekstu w Twojej stronie, więc to, czy tekst jest „duży”, musisz ocenić sam. Spełnione 1.4.3 i 1.4.11 to także tylko część WCAG: strona z poprawnym kontrastem może mieć inne bariery. Po zmianach kolorów przejrzyj ją w rzeczywistym układzie, w jasnym i ciemnym motywie.