TL;DR
Контрастность текста — ключевой параметр доступности. WCAG требует соотношения 4.5:1 для обычного текста и 3:1 для крупного. Разбираемся, как считать контраст правильно, какие типичные ошибки допускают разработчики и как их исправить.
Введение: Почему это важно
Каждый второй аудит доступности находит проблемы с цветовым контрастом. Lighthouse ругается, дизайнеры получают замечания, но многие до сих пор не понимают, как именно работает контрастность по WCAG.
Главный миф: “Достаточно сделать текст темнее фона”. На деле — восприятие яркости нелинейно, и простого сравнения RGB значений недостаточно.
Как считается контрастность
Формула WCAG для соотношения контрастов:
contrastRatio = (L1 + 0.05) / (L2 + 0.05)
Где:
- L1 — яркость более светлого цвета
- L2 — яркость более темного
Яркость (luminance) считается через преобразование цветов:
function getLuminance(r, g, b) {
const [lr, lg, lb] = [r, g, b].map(c =>
c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)
);
return 0.2126 * lr + 0.7152 * lg + 0.0722 * lb;
}
Требования WCAG 2.1
Уровень AA (минимум для compliance):
- Обычный текст (<18pt или <14pt bold): 4.5:1
- Крупный текст (≥18pt или ≥14pt bold): 3:1
Уровень AAA (расширенная доступность):
- Обычный текст: 7:1
- Крупный текст: 4.5:1
Типичные ошибки в UI
1. Placeholder в input
Браузеры по умолчанию используют серый цвет с opacity 0.4. Многие копируют это через color: #999 на белом фоне — контраст всего 2.8:1.
Решение:
Используйте #767676 — дает 4.5:1 на белом фоне.
2. Серый текст на белом фоне
“Мутный” текст (#AAA или #999) не проходит AA. Минимальный серый для белого фона — #767676.
3. Цветные кнопки
Синие кнопки (#1A73E8) с белым текстом дают ~3:1 — проходит только для крупного текста. Для мелкого нужно использовать более темный синий.
4. Брендовые цвета
Зеленый #2F855A на белом: ~5.1:1 (проходит).
Но на светло-сером фоне #F5F6FA: ~4.6:1 — близко к границе.
5. Статусные баджи
Желтый #FBBF24 на белом: ~1.7:1 (провал).
Лучше использовать #D97706 с желтым фоном.
Как проверять контрастность
- DevTools: В панели Color Picker Chrome/Firefox показывают WCAG-соответствие.
- Инструменты:
Что делать, если контраст недостаточен
-
Для текста:
- Увеличить размер (переход в категорию “крупный текст”)
- Сделать текст жирным (14pt+ bold = крупный текст)
- Использовать более темный цвет
-
Для компонентов:
- Добавить границу
- Использовать иконки с метками
Будущее: APCA
WCAG 3.0 вводит новый алгоритм APCA, который учитывает:
- Размер текста
- Насыщенность шрифта
- Полярность (светлый/темный режим)
Пока стандарт — WCAG 2.1, но APCA уже стоит иметь в виду.
Заключение
80% проблем с контрастом сводятся к:
- Placeholder в формах
- Вторичный текст
- Брендовые кнопки
Проверяйте эти элементы в первую очередь. Доступность — не роскошь, а must-have для современного фронтенда.