Color Contrast Checker
Перевірте співвідношення контрастності WCAG AA та AAA між кольором переднього плану та фону
Колір переднього плану (текст)
Колір фону
Зразок великого тексту (18px жирний)
Зразок звичайного тексту — так виглядатиме ваш основний текст на обраному кольорі фону.
Коефіцієнт контрастності
14.63:1
Відповідність WCAG
Пройдено
Звичайний AA
Пройдено
Звичайний AAA
Пройдено
Великий AA
Пройдено
Великий AAA
WCAG AA — Звичайний текст: 4.5:1, Великий текст (18px+ або 14px жирний): 3:1
WCAG AAA — Звичайний текст: 7:1, Великий текст (18px+ або 14px жирний): 4.5:1
Що таке перевірка контрастності кольорів?
Перевірка контрастності кольорів вимірює різницю яскравості між кольором переднього плану (зазвичай текстом) та кольором фону, а потім виражає результат у вигляді коефіцієнта. Коефіцієнт 1:1 означає, що кольори ідентичні; 21:1 — максимум, що відповідає чорному на білому або навпаки. Посібник з доступності вебвмісту (WCAG), опублікований консорціумом W3C, визначає мінімальні коефіцієнти контрастності, яким має відповідати текст, щоб люди з порушеннями зору або дефектами колірного сприйняття могли його читати.
Формула обчислення коефіцієнта контрастності походить зі специфікації WCAG 2.x і ґрунтується на відносній яскравості — показнику того, наскільки яскравим здається колір людському оку. Відносна яскравість обчислюється шляхом лінеаризації кожного каналу sRGB (видалення гамма-корекції) та зважування каналів відповідно до коефіцієнтів ITU-R BT.709: 0,2126 для червоного, 0,7152 для зеленого та 0,0722 для синього. Зелений колір вносить найбільший внесок, оскільки людський зір найбільш чутливий до нього. Коефіцієнт обчислюється як (L1 + 0,05) / (L2 + 0,05), де L1 — яскравість світлішого кольору.
WCAG визначає два рівні відповідності. Рівень AA вимагає коефіцієнта контрастності не менше 4,5:1 для звичайного тексту та 3:1 для великого тексту (18px або більше, або 14px жирний). Рівень AAA підвищує вимоги до 7:1 та 4,5:1 відповідно. WCAG 2.1 також ввів критерій успішності 1.4.11, який вимагає коефіцієнта 3:1 для нетекстових елементів інтерфейсу, таких як межі, іконки та індикатори фокусу.
Чому варто використовувати цей перевірник контрастності?
Перевірка контрастності на власний погляд ненадійна. Кольори, що виглядають чіткими на вашому відкаліброваному моніторі, можуть зливатися на екрані низькоякісного ноутбука, під прямими сонячними променями або для людини з дейтеранопією. Числовий коефіцієнт усуває здогадки та дає чіткий результат «пройдено/не пройдено» відповідно до стандарту WCAG.
Випадки використання перевірника контрастності
Вимоги WCAG до коефіцієнта контрастності
Таблиця нижче узагальнює мінімальні коефіцієнти контрастності, що вимагаються WCAG 2.1 для різних типів вмісту та рівнів відповідності. Великий текст визначається як 18px (24 CSS пікселі) або більше при звичайному насиченні, або 14px (18,66 CSS пікселів) або більше при жирному насиченні.
| Рівень | Мін. коефіцієнт | Застосовується до | Примітка |
|---|---|---|---|
| AA Normal text | 4.5 : 1 | Body text, paragraphs, labels | Minimum for most UI text |
| AA Large text | 3.0 : 1 | Text >= 18px, or >= 14px bold | Minimum for headings |
| AA UI components | 3.0 : 1 | Borders, icons, focus indicators | Non-text contrast (WCAG 1.4.11) |
| AAA Normal text | 7.0 : 1 | Body text at highest standard | Enhanced readability |
| AAA Large text | 4.5 : 1 | Large text at highest standard | Enhanced for headings |
Пояснення яскравості, AA та AAA
Обчислення коефіцієнта контрастності складається з трьох етапів: обчислення яскравості для кожного кольору, визначення коефіцієнта та порівняння його з порогами WCAG.
Приклади коду
Обчислення коефіцієнтів контрастності WCAG програмним шляхом. Кожен приклад реалізує формулу відносної яскравості зі специфікації WCAG 2.x та обчислення коефіцієнта контрастності. Для порівняння тестуються ті самі пари чорного на білому та індиго на білому.
// Calculate relative luminance per WCAG 2.x (sRGB)
function luminance(r, g, b) {
const [rs, gs, bs] = [r, g, b].map(c => {
c /= 255
return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)
})
return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs
}
// Contrast ratio between two RGB colors
function contrastRatio(fg, bg) {
const l1 = luminance(...fg)
const l2 = luminance(...bg)
const lighter = Math.max(l1, l2)
const darker = Math.min(l1, l2)
return (lighter + 0.05) / (darker + 0.05)
}
contrastRatio([0, 0, 0], [255, 255, 255]) // -> 21.0
contrastRatio([99, 102, 241], [255, 255, 255]) // -> 3.95
contrastRatio([29, 78, 216], [255, 255, 255]) // -> 6.06 (AA pass)def luminance(r: int, g: int, b: int) -> float:
"""Relative luminance per WCAG 2.x, ITU-R BT.709 coefficients."""
channels = []
for c in (r, g, b):
c /= 255
channels.append(c / 12.92 if c <= 0.04045 else ((c + 0.055) / 1.055) ** 2.4)
return 0.2126 * channels[0] + 0.7152 * channels[1] + 0.0722 * channels[2]
def contrast_ratio(fg: tuple, bg: tuple) -> float:
l1 = luminance(*fg)
l2 = luminance(*bg)
lighter, darker = max(l1, l2), min(l1, l2)
return (lighter + 0.05) / (darker + 0.05)
print(f"{contrast_ratio((0, 0, 0), (255, 255, 255)):.2f}") # -> 21.00
print(f"{contrast_ratio((99, 102, 241), (255, 255, 255)):.2f}") # -> 3.95
# Check WCAG AA for normal text
ratio = contrast_ratio((29, 78, 216), (255, 255, 255))
print(f"{ratio:.2f} — {'AA pass' if ratio >= 4.5 else 'AA fail'}") # -> 6.06 — AA passpackage main
import (
"fmt"
"math"
)
func linearize(c float64) float64 {
c /= 255
if c <= 0.04045 {
return c / 12.92
}
return math.Pow((c+0.055)/1.055, 2.4)
}
func luminance(r, g, b int) float64 {
return 0.2126*linearize(float64(r)) +
0.7152*linearize(float64(g)) +
0.0722*linearize(float64(b))
}
func contrastRatio(fgR, fgG, fgB, bgR, bgG, bgB int) float64 {
l1 := luminance(fgR, fgG, fgB)
l2 := luminance(bgR, bgG, bgB)
lighter := math.Max(l1, l2)
darker := math.Min(l1, l2)
return (lighter + 0.05) / (darker + 0.05)
}
func main() {
ratio := contrastRatio(0, 0, 0, 255, 255, 255)
fmt.Printf("%.2f\n", ratio) // -> 21.00
ratio = contrastRatio(29, 78, 216, 255, 255, 255)
fmt.Printf("%.2f\n", ratio) // -> 6.06 (AA pass for normal text)
}/* WCAG-safe color pairs — tested contrast ratios */
/* 12.63:1 — passes AAA normal text */
.high-contrast {
color: #1e293b; /* slate-800 */
background: #f8fafc; /* slate-50 */
}
/* 7.07:1 — passes AAA normal text */
.dark-theme-text {
color: #e2e8f0; /* slate-200 */
background: #0f172a; /* slate-900 */
}
/* 4.57:1 — passes AA normal, fails AAA */
.accent-on-white {
color: #1d4ed8; /* blue-700 */
background: #ffffff;
}
/* 2.14:1 — fails AA for text, but passes 3:1 for large text */
.muted-heading {
color: #94a3b8; /* slate-400 */
background: #ffffff;
}