Kontrast RGB względem WCAG – jak go obliczyć i poprawić
Kontrast kolorów w projektowaniu stron internetowych jest kluczowym aspektem dostępności (WCAG – Web Content Accessibility Guidelines). Niski kontrast między tekstem a tłem może powodować problemy z czytelnością, szczególnie dla osób z wadami wzroku. WCAG określa minimalne współczynniki kontrastu, aby tekst był czytelny:
Klasa AA
- 4.5:1 dla normalnego tekstu
- 3.0:1 dla dużego tekstu 18pt (24px) i większy lub 14pt (19px) pogrubiony
Klasa AAA
- 7.0:1 dla normalnego tekstu
- 4.5:1 dla dużego tekstu 18pt (24px) i większy lub 14pt (19px) pogrubiony
W tym artykule przedstawimy, jak obliczyć kontrast kolorów RGB oraz jak dobrać odpowiednie klasy w Bootstrap 5.3, aby spełnić wymagania WCAG.
Jak obliczyć kontrast według WCAG
Kontrast między dwoma kolorami oblicza się według wzoru:
$${contrast \text{ } ratio} = \frac{L1 + 0.05}{L2 + 0.05} $$
gdzie:
- L1 to większa wartość luminancji względnej (jaśniejszy kolor)
- L2 to mniejsza wartość luminancji względnej (ciemniejszy kolor)
Luminancję względną koloru RGB oblicza się następująco:
- Przekształcenie wartości kanałów RGB (0-255) na zakres 0-1: $$R' = R/255, \quad G' = G/255, \quad B' = B/255$$
- Przekształcenie liniowe:
- Jeśli wartość $$(X' \leq 0.03928), \text{ }to\text{ } (X = X' / 12.92)$$
- W przeciwnym razie: $$(X = ((X' + 0.055) / 1.055) ^{2.4})$$
- Luminancja względna: $$L = 0.2126R + 0.7152G + 0.0722B$$
Funkcja w JavaScript do obliczania kontrastu
function getLuminance(r, g, b) {
let [R, G, B] = [r, g, b].map(value => {
let v = value / 255;
return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
});
return 0.2126 * R + 0.7152 * G + 0.0722 * B;
}
function getContrastRatio(color1, color2) {
let L1 = getLuminance(...color1);
let L2 = getLuminance(...color2);
let ratio = (Math.max(L1, L2) + 0.05) / (Math.min(L1, L2) + 0.05);
return ratio.toFixed(2);
}
console.log(getContrastRatio([33, 37, 41], [255, 255, 255])); // Przykład dla tekstu text-dark na białym tle
Bootstrap 5.3 – klasy z niskim kontrastem
W Bootstrap 5.3 domyślnie dostępne są klasy, które mogą powodować niewystarczający kontrast na jasnym lub ciemnym tle:
Przykłady niskiego kontrastu:
- Na jasnym tle
bg-light(#f8f9fa).text-primary(niebieski:#0d6efd) → Kontrast: ~4.26:1 (za niski).text-info(jasny błękit:#0dcaf0) → Kontrast: ~1.85:1 (bardzo niski)
- Na ciemnym tle
bg-dark(#212529).text-secondary(szary:#6c757d) → Kontrast: ~3.28:1 (za niski).text-danger(czerwony:#dc3545) → Kontrast: ~3.4:1 (za niski)
Zalecane klasy o wysokim kontraście
Aby spełnić WCAG, warto używać kombinacji kolorów o współczynniku ≥ 4.5:1. Przykłady bezpiecznych klas:
Dla jasnego tła bg-light (#f8f9fa):
.text-dark(#212529) → Kontrast: 14.63:1 (bardzo dobry wybór).text-black(#000000) → Kontrast: 19.92:1 (świetny wybór)
Dla ciemnego tła bg-dark (#212529):
.text-white(#ffffff) → Kontrast: 15.42:1 (świetny wybór).text-light(#f8f9fa) → Kontrast: 14.63:1 (bardzo dobry wybór)
Jeśli chcesz dostosować kontrast jeszcze lepiej, można nadpisać kolory w CSS:
.text-high-contrast-primary {
color: #004085; /* Ciemniejszy niebieski, lepszy kontrast */
}
.text-high-contrast-warning {
color: #856404; /* Ciemniejszy żółty */
}
Zestawienie kolorów i kontrastów w tabeli
Zestawienie kontrastów i zgodności z WCAG AA (min. 4.5:1) oraz AAA (min. 7.0:1) dla normalnego tekstu.
| Klasa tekstu | bg-white (#ffffff) |
bg-light (#f8f9fa) |
bg-dark (#212529) |
bg-black (#000000) |
|---|---|---|---|---|
text-primary (#0d6efd) |
4.5:1 ✓ AA ✗ AAA | 4.26:1 ✗ AA ✗ AAA | 3.42:1 ✗ AA ✗ AAA | 4.66:1 ✓ AA ✗ AAA |
text-secondary (#6c757d) |
4.68:1 ✓ AA ✗ AAA | 4.44:1 ✗ AA ✗ AAA | 3.28:1 ✗ AA ✗ AAA | 4.47:1 ✗ AA ✗ AAA |
text-success (#198754) |
4.53:1 ✓ AA ✗ AAA | 4.29:1 ✗ AA ✗ AAA | 3.4:1 ✗ AA ✗ AAA | 4.63:1 ✓ AA ✗ AAA |
text-info (#0dcaf0) |
1.95:1 ✗ AA ✗ AAA | 1.85:1 ✗ AA ✗ AAA | 7.87:1 ✓ AA ✓ AAA | 10.72:1 ✓ AA ✓ AAA |
text-warning (#ffc107) |
1.63:1 ✗ AA ✗ AAA | 1.54:1 ✗ AA ✗ AAA | 9.46:1 ✓ AA ✓ AAA | 12.88:1 ✓ AA ✓ AAA |
text-danger (#dc3545) |
4.52:1 ✓ AA ✗ AAA | 4.29:1 ✗ AA ✗ AAA | 3.4:1 ✗ AA ✗ AAA | 4.63:1 ✓ AA ✗ AAA |
text-light (#f8f9fa) |
1.05:1 ✗ AA ✗ AAA | 1:1 ✗ AA ✗ AAA | 14.63:1 ✓ AA ✓ AAA | 19.92:1 ✓ AA ✓ AAA |
text-dark (#212529) |
15.42:1 ✓ AA ✓ AAA | 14.63:1 ✓ AA ✓ AAA | 1:1 ✗ AA ✗ AAA | 1.36:1 ✗ AA ✗ AAA |
text-black (#000000) |
21:1 ✓ AA ✓ AAA | 19.92:1 ✓ AA ✓ AAA | 1.36:1 ✗ AA ✗ AAA | 1:1 ✗ AA ✗ AAA |
text-white (#ffffff) |
1:1 ✗ AA ✗ AAA | 1.05:1 ✗ AA ✗ AAA | 15.42:1 ✓ AA ✓ AAA | 21:1 ✓ AA ✓ AAA |
Zestawienie kontrastów i zgodności z WCAG AA (min. 3.0:1) oraz AAA (min. 4.5:1) dla dużego lub pogrubionego tekstu.
| Klasa tekstu | bg-white (#ffffff) |
bg-light (#f8f9fa) |
bg-dark (#212529) |
bg-black (#000000) |
|---|---|---|---|---|
text-primary (#0d6efd) |
4.5:1 ✓ AA ✓ AAA | 4.26:1 ✓ AA ✗ AAA | 3.42:1 ✓ AA ✗ AAA | 4.66:1 ✓ AA ✓ AAA |
text-secondary (#6c757d) |
4.68:1 ✓ AA ✓ AAA | 4.44:1 ✓ AA ✗ AAA | 3.28:1 ✓ AA ✗ AAA | 4.47:1 ✓ AA ✗ AAA |
text-success (#198754) |
4.53:1 ✓ AA ✓ AAA | 4.29:1 ✓ AA ✗ AAA | 3.4:1 ✓ AA ✗ AAA | 4.63:1 ✓ AA ✓ AAA |
text-info (#0dcaf0) |
1.95:1 ✗ AA ✗ AAA | 1.85:1 ✗ AA ✗ AAA | 7.87:1 ✓ AA ✓ AAA | 10.72:1 ✓ AA ✓ AAA |
text-warning (#ffc107) |
1.63:1 ✗ AA ✗ AAA | 1.54:1 ✗ AA ✗ AAA | 9.46:1 ✓ AA ✓ AAA | 12.88:1 ✓ AA ✓ AAA |
text-danger (#dc3545) |
4.52:1 ✓ AA ✓ AAA | 4.29:1 ✓ AA ✗ AAA | 3.4:1 ✓ AA ✗ AAA | 4.63:1 ✓ AA ✓ AAA |
text-light (#f8f9fa) |
1.05:1 ✗ AA ✗ AAA | 1:1 ✗ AA ✗ AAA | 14.63:1 ✓ AA ✓ AAA | 19.92:1 ✓ AA ✓ AAA |
text-dark (#212529) |
15.42:1 ✓ AA ✓ AAA | 14.63:1 ✓ AA ✓ AAA | 1:1 ✗ AA ✗ AAA | 1.36:1 ✗ AA ✗ AAA |
text-black (#000000) |
21:1 ✓ AA ✓ AAA | 19.92:1 ✓ AA ✓ AAA | 1.36:1 ✗ AA ✗ AAA | 1:1 ✗ AA ✗ AAA |
text-white (#ffffff) |
1:1 ✗ AA ✗ AAA | 1.05:1 ✗ AA ✗ AAA | 15.42:1 ✓ AA ✓ AAA | 21:1 ✓ AA ✓ AAA |
Sprawdź kontrast WCAG
Podsumowanie
Zapewnienie odpowiedniego kontrastu tekstu względem tła to kluczowy element dostępności stron. Dzięki prostym obliczeniom i odpowiedniemu doborowi klas Bootstrap 5.3 możemy znacząco poprawić czytelność i spełnić wymagania WCAG. Warto korzystać z narzędzi takich jak funkcja JavaScript do analizy kontrastu i unikać klas o zbyt niskim współczynniku kontrastu.