Przejdź do treści
HNarzędzia
pl
Kategorie

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.

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() i oklch(). 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.

Narzędzie Kontrast kolorów z białym tekstem na tle #4A90E2: współczynnik 3,29:1, poniżej propozycja ciemniejszego tła #3278C9 (4,50:1) i ciemniejszego tekstu #272727 (4,54:1)

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

Narzędzie Pipeta kolorów ze zdjęcia z syntetycznym banerem w gradiencie błękitu: z prawej części obrazu pobrany został kolor #90B7EB

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.