Контрастность цвета для соответствия WCAG: Руководство по стандартам AA и AAA
Вы разрабатываете веб-сайт или приложение, но не уверены, доступны ли ваши цветовые решения для пользователей с нарушениями зрения. Ваш дизайнер выбрал цвета, которые отлично выглядят, но не проходят аудит доступности. Это руководство объясняет требования WCAG к контрастности цвета, как тестировать коэффициенты контрастности и как исправлять распространённые ошибки, сохраняя визуальную привлекательность.
Понимание требований WCAG к контрастности
WCAG (Руководство по доступности веб-контента) определяет минимальные коэффициенты контрастности между цветом текста и фона для обеспечения читаемости для пользователей с:
- Слабым зрением: Сниженная острота зрения
- Нарушениями цветовосприятия: Дальтонизм (8% мужчин, 0,5% женщин)
- Возрастной потерей зрения: Чувствительность к контрасту снижается с возрастом
- Условиями окружающей среды: Блики, яркий солнечный свет, дисплеи низкого качества
Уровни WCAG: AA против AAA
| Уровень | Обычный текст | Крупный текст | Цель |
|---|---|---|---|
| AA | 4.5:1 | 3:1 | Юридическое соответствие, большинство сайтов |
| AAA | 7:1 | 4.5:1 | Повышенная доступность, правительство, здравоохранение |
Крупный текст определяется как:
- 18pt+ (24px+) для обычного начертания
- 14pt+ (18.66px+) для жирного начертания (700+)
Что такое коэффициент контрастности?
Коэффициент контрастности измеряет разницу в яркости (воспринимаемой яркости) между двумя цветами:
Коэффициент контрастности = (L1 + 0.05) / (L2 + 0.05)
Где:
- L1 = относительная яркость более светлого цвета
- L2 = относительная яркость более тёмного цвета
- Диапазон: 1:1 (нет контраста) до 21:1 (максимальный контраст)
Примеры:
Чёрный на белом: 21:1 (максимальный контраст)
#767676 на белом: 4.54:1 (AA прошёл)
#595959 на белом: 7.0:1 (AAA прошёл)
Белый на белом: 1:1 (не прошёл)Визуальная справка по коэффициенту контрастности
| Коэффициент | Пример (на белом) | Читаемость | Статус WCAG |
|---|---|---|---|
| 21:1 | #000000 (чёрный) | Отличная | AAA прошёл |
| 12:1 | #424242 (тёмно-серый) | Отличная | AAA прошёл |
| 7:1 | #595959 (средне-тёмно-серый) | Очень хорошая | AAA прошёл |
| 4.5:1 | #767676 (средне-серый) | Хорошая | AA прошёл |
| 3:1 | #959595 (светло-средне-серый) | Удовлетворительная (только крупный текст) | AA крупный текст |
| 2:1 | #BABABA (светло-серый) | Плохая | Не прошёл |
Тестирование контрастности цвета
Ручное тестирование с помощью проверки контрастности
Используйте Проверку контрастности цветов для тестирования ваших цветовых пар:
Процесс тестирования:
1. Введите цвет переднего плана (цвет текста)
2. Введите цвет фона
3. Просмотрите коэффициент контрастности
4. Проверьте соответствие WCAG AA/AAA
5. При необходимости настройте цвета
Пример теста:
Передний план: #3B82F6 (синий)
Фон: #FFFFFF (белый)
Коэффициент: 3.13:1
Результат: ❌ Не прошёл AA (требуется 4.5:1)
Исправление: Затемните синий до #1D4ED8
Новый коэффициент: 7.2:1
Результат: ✓ Прошёл AAAТестирование с помощью инструментов разработчика браузера
Chrome DevTools:
- Откройте DevTools (F12)
- Выберите элемент с текстом
- На панели Styles кликните на выборщик цвета рядом со значением цвета
- Просмотрите коэффициент контрастности под выборщиком цвета
- Увидьте индикаторы прохождения/непрохождения AA/AAA
Firefox DevTools:
- Откройте DevTools (F12)
- Перейдите на вкладку Accessibility
- Выберите "Check for issues" → "All Issues"
- Просмотрите предупреждения о контрастности с конкретными коэффициентами
Автоматизированное тестирование
Используйте расширения браузера для сканирования всей страницы:
- axe DevTools: Комплексное тестирование доступности
- WAVE: Визуальная обратная связь о проблемах доступности
- Lighthouse: Встроено в Chrome DevTools (панель Audits)
Запуск аудита Lighthouse:
1. Откройте Chrome DevTools → вкладка Lighthouse
2. Выберите категорию "Accessibility"
3. Кликните "Analyze page load"
4. Просмотрите ошибки контрастности в отчёте
Пример вывода:
✓ 15 проверок контрастности пройдено
✗ 3 элемента с недостаточным контрастом:
- Кнопка: 2.8:1 (требуется 4.5:1)
- Ссылка: 3.1:1 (требуется 4.5:1)
- Метка: 2.5:1 (требуется 4.5:1)Распространённые ошибки контрастности и их исправления
Ошибка 1: Светло-серый текст на белом
Проблема: Вторичный текст, заполнители и отключённые состояния часто используют светло-серый, который не проходит требования контрастности.
❌ Не проходящие примеры:
#CCCCCC на #FFFFFF → 1.6:1 (не прошёл)
#999999 на #FFFFFF → 2.8:1 (не прошёл)
#AAAAAA на #FFFFFF → 2.3:1 (не прошёл)
✓ Доступные альтернативы:
#757575 на #FFFFFF → 4.5:1 (AA прошёл)
#595959 на #FFFFFF → 7.0:1 (AAA прошёл)
#616161 на #FFFFFF → 6.5:1 (AAA прошёл)Стратегия исправления: Затемните текст на 30-40%, сохраняя визуальную иерархию.
Ошибка 2: Фирменные цвета с недостаточным контрастом
Проблема: Фирменные цвета (особенно синие, светло-зелёные, оранжевые) часто не проходят на белом фоне.
Примеры фирменных цветов:
Основной синий: #3B82F6
- На белом: 3.13:1 ❌
- Исправление: #1D4ED8 → 7.2:1 ✓
Зелёный успеха: #10B981
- На белом: 1.93:1 ❌
- Исправление: #047857 → 4.93:1 ✓
Предупреждающий оранжевый: #F59E0B
- На белом: 1.93:1 ❌
- Исправление: #D97706 → 3.1:1 (только крупный текст)
- Лучшее исправление: #B45309 → 4.7:1 ✓Стратегия исправления:
- Вариант 1: Создайте более тёмный вариант фирменного цвета для текста (например, primary-600 вместо primary-500)
- Вариант 2: Используйте белый текст на фоне фирменного цвета (проверьте и этот контраст)
- Вариант 3: Добавьте обводку или тень текста (не рекомендуется, сложнее читать)
Ошибка 3: Цветные ссылки на цветных фонах
Проблема: Синие ссылки на светло-синем фоне или любой цвет ссылки, который сливается с фоном.
Пример сценария:
Фон: #EFF6FF (светло-синий)
Ссылка: #3B82F6 (синий)
Контраст: 2.1:1 ❌
Решения:
1. Затемните ссылку:
Ссылка: #1D4ED8 → 4.2:1 ✓
2. Измените фон:
Фон: #FFFFFF (белый)
Ссылка: #3B82F6 → 3.13:1 ❌ (всё равно не прошёл)
Ссылка всё равно требует затемнения
3. Добавьте подчёркивание:
Ссылка с подчёркиванием + контраст 3:1 = приемлемо
(WCAG разрешает 3:1 при наличии дополнительного индикатора)Ошибка 4: Текст-заполнитель
Проблема: Стандартный браузерный текст-заполнитель часто слишком светлый (обычно #999999 или подобный).
❌ Стандартный заполнитель (большинство браузеров):
color: #999999;
Контраст на белом: 2.8:1 (не прошёл)
✓ Доступный заполнитель:
input::placeholder {
color: #6B7280; /* 4.6:1 на белом */
}
Примечание: WCAG 2.1 НЕ требует, чтобы текст-заполнитель
соответствовал минимумам контрастности (требуется только для
меток и фактического текста ввода). Однако лучший
контраст улучшает удобство использования для всех.Ошибка 5: Отключённые элементы управления формы
Проблема: Отключённые кнопки и поля ввода часто используют очень светлые цвета, которые не проходят контрастность.
Исключение WCAG: Отключённые элементы управления НЕ обязаны соответствовать минимумам контрастности по WCAG 2.1. Однако пользователи могут испытывать трудности с их видимостью.
Подход 1: Пропустить контраст (соответствует WCAG)
button:disabled {
color: #CCCCCC; /* 1.6:1 - допустимо по WCAG */
background: #F3F4F6;
cursor: not-allowed;
}
Подход 2: Лучшее удобство использования (рекомендуется)
button:disabled {
color: #9CA3AF; /* 3.2:1 - всё ещё видимо */
background: #E5E7EB;
opacity: 0.6; /* Визуальный индикатор отключённого состояния */
cursor: not-allowed;
}Создание доступных цветовых палитр
Создание шкалы, соответствующей WCAG
Создавайте вашу цветовую систему с учётом контрастности с самого начала:
Пример: Шкала серого для текста
На белом фоне (#FFFFFF):
--gray-900: #111827 (16.8:1) → Основной текст (AAA)
--gray-800: #1F2937 (13.4:1) → Заголовки (AAA)
--gray-700: #374151 (10.2:1) → Подзаголовки (AAA)
--gray-600: #4B5563 (7.6:1) → Вторичный текст (AAA)
--gray-500: #6B7280 (4.6:1) → Третичный текст (AA)
--gray-400: #9CA3AF (2.8:1) → Отключённый (не прошёл - использовать экономно)
--gray-300: #D1D5DB (1.7:1) → Только границы (не для текста)
--gray-200: #E5E7EB (1.3:1) → Только фоны
--gray-100: #F3F4F6 (1.1:1) → Только светлые фоны
Правило: Используйте gray-500 или темнее для всего текстаСтратегия многоцветной системы
Для каждого фирменного цвета создайте варианты для разных случаев использования:
Система основного синего:
--primary-900: #1E3A8A (11.2:1) → Заголовки на белом
--primary-800: #1E40AF (9.3:1) → Ссылки на белом (AAA)
--primary-700: #1D4ED8 (7.2:1) → Ссылки на белом (AAA)
--primary-600: #2563EB (5.1:1) → Ссылки на белом (AA)
--primary-500: #3B82F6 (3.1:1) → Крупный текст, фоны
--primary-400: #60A5FA (2.1:1) → Только фоны
--primary-300: #93C5FD (1.5:1) → Светлые фоны
Правила использования:
- Текст на белом: Используйте 600+ (AA) или 700+ (AAA)
- Фоны с белым текстом: Используйте 600+
- Кнопки: Фон 500+, текст белый или 900
- Значки: Фон 100-300, текст 900Особенности тёмного режима
Тёмный режим требует других подходов к контрастности:
Проблемы тёмного режима:
1. Белый текст на чисто чёрном (#000000) может вызывать
"гало" (эффект свечения) у некоторых пользователей
2. Очень высокий контраст (21:1) может быть некомфортным
в условиях низкой освещённости
3. Многие цвета, работающие на белом, не проходят на тёмном
Рекомендуемая основа тёмного режима:
Фон: #0F172A (не чисто чёрный)
Основной текст: #E2E8F0 (15.8:1 на #0F172A)
Вторичный: #94A3B8 (8.3:1 на #0F172A)
Настроенные фирменные цвета для тёмного режима:
--primary-dark: #60A5FA (светлее, чем в светлом режиме)
--success-dark: #34D399 (светлее)
--warning-dark: #FBBF24 (светлее)Особые случаи и исключения
Когда требования контрастности не применяются
WCAG 2.1 исключает:
- Логотипы и фирменные названия: Нет требования контрастности
- Случайный текст: Текст на фотографиях, чистое украшение
- Неактивные компоненты UI: Отключённые кнопки, серые пункты меню
- Текст, являющийся частью неактивного пользовательского интерфейса: Элементы, с которыми пользователь не может взаимодействовать
Исключение крупного текста
Крупный текст (18pt+/24px+ или 14pt+/18.66px+ жирный) требует только контраста 3:1 для соответствия AA:
Пример: Заголовки героя
Заголовок: 48px, font-weight: 700
Цвет: #93C5FD (светло-синий)
Фон: #FFFFFF (белый)
Контраст: 1.5:1
❌ Не прошёл AA для крупного текста (требуется 3:1)
✓ Затемнение до #3B82F6 → 3.1:1 (AA прошёл для крупного текста)
Примечание: Всё ещё не прошёл AA для обычного текста (требуется 4.5:1)Компоненты UI (WCAG 2.1 Уровень AA 1.4.11)
Нетекстовый контраст: Компоненты UI и графические объекты требуют контраста 3:1 к соседним цветам:
- Поля формы: Граница должна быть 3:1 к фону
- Кнопки: Фон кнопки должен быть 3:1 к фону страницы
- Индикаторы фокуса: Должны быть 3:1 к фону
- Иконки: Должны быть 3:1 (если значимые, не декоративные)
Пример: Граница поля ввода
Фон: #FFFFFF (белый)
Граница поля ввода: #E5E7EB (светло-серый)
Контраст: 1.3:1 ❌
Варианты исправления:
1. Затемните границу: #D1D5DB → 1.7:1 ❌ (всё ещё не прошёл)
2. Затемните больше: #9CA3AF → 2.8:1 ❌ (всё ещё не прошёл)
3. Затемните достаточно: #6B7280 → 4.6:1 ✓
Альтернативный подход:
Используйте едва заметный фон вместо:
Фон поля ввода: #F9FAFB
Граница поля ввода: #D1D5DB
Граница vs фон: 1.3:1 (но приемлемо, если
поле ввода имеет контраст 3:1 к фону страницы)Реальные паттерны дизайна
Паттерн 1: Синяя ссылка на белом
/* ❌ Распространённая ошибка */
a {
color: #3B82F6; /* Tailwind blue-500 */
}
/* Контраст: 3.13:1 - не прошёл AA */
/* ✓ Соответствует AA */
a {
color: #1D4ED8; /* Tailwind blue-700 */
}
/* Контраст: 7.2:1 - прошёл AAA */
/* ✓ Альтернатива: подчёркивание + меньший контраст */
a {
color: #3B82F6; /* 3.1:1 */
text-decoration: underline;
}
/* WCAG разрешает 3:1 с дополнительным индикатором */Паттерн 2: Значки состояния
Система значков состояния:
/* ❌ Не проходящий дизайн */
.badge-success {
background: #ECFDF5; /* Очень светло-зелёный */
color: #10B981; /* Средне-зелёный */
}
/* Контраст: 1.4:1 - не прошёл */
/* ✓ Соответствует AA */
.badge-success {
background: #D1FAE5; /* Светло-зелёный */
color: #065F46; /* Тёмно-зелёный */
}
/* Контраст: 9.2:1 - прошёл AAA */
/* ✓ Альтернатива: более сильный фон */
.badge-success {
background: #10B981; /* Средне-зелёный */
color: #FFFFFF; /* Белый */
}
/* Контраст: 3.4:1 - прошёл AA для крупного текста */
/* Используйте больший размер шрифта (14px+) и жирный */Паттерн 3: Состояния при наведении на карточки
Индикация при наведении с доступным контрастом:
/* ❌ Едва заметное наведение (может не пройти) */
.card {
background: #FFFFFF;
border: 1px solid #E5E7EB;
}
.card:hover {
background: #F9FAFB; /* Очень едва заметно */
border-color: #D1D5DB;
}
/* Изменение фона: 1.2:1 - трудно увидеть */
/* ✓ Чёткая индикация при наведении */
.card {
background: #FFFFFF;
border: 1px solid #E5E7EB;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.card:hover {
border-color: #3B82F6; /* Синий */
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
/* Изменение границы видимо, тень усиливает */Паттерн 4: Валидация форм
Состояние ошибки с доступным контрастом:
/* ❌ Светлое состояние ошибки */
.input-error {
border-color: #FCA5A5; /* Светло-красный */
color: #EF4444; /* Средне-красный */
}
/* Контраст границы: 1.8:1 - не прошёл */
/* ✓ Чёткое состояние ошибки */
.input-error {
border-color: #DC2626; /* Тёмно-красный, 5.3:1 */
color: #991B1B; /* Очень тёмно-красный, 9.4:1 */
background: #FEF2F2; /* Очень светло-красный */
}
/* Все контрасты прошли AA */
Сообщение об ошибке:
.error-message {
color: #991B1B; /* 9.4:1 на белом - AAA прошёл */
font-size: 14px;
margin-top: 4px;
}Процесс тестирования для дизайнеров и разработчиков
Фаза дизайна (перед разработкой)
- Создайте цветовую палитру: Используйте Проверку контрастности цветов для тестирования каждого цвета текста на фонах
- Задокументируйте проходящие комбинации: Создайте руководство по стилю, показывающее какие цвета работают вместе
- Тестируйте в инструменте дизайна: Используйте плагины Figma (Contrast, A11y - Color Contrast Checker)
- Учитывайте дальтонизм: Используйте Симулятор дальтонизма для проверки работы дизайнов для всех пользователей
Фаза разработки (реализация)
- Используйте предварительно протестированные цвета: Ссылайтесь на руководство по стилю из фазы дизайна
- Тестируйте компоненты: Проверяйте контраст в выборщике цвета DevTools браузера
- Запустите автоматизированный аудит: Используйте Lighthouse или axe DevTools
- Исправьте ошибки: Итерируйте цвета до прохождения
Фаза QA (перед запуском)
- Полностраничный аудит: Запустите WAVE или axe DevTools на всех страницах
- Ручное тестирование: Проверьте состояния при наведении, индикаторы фокуса, модальные окна
- Тёмный режим: Проверьте, что все цвета работают и в тёмном режиме
- Задокументируйте исключения: Отметьте любые декоративные элементы, освобождённые от WCAG
Краткая справка: Распространённые доступные цвета
На белом фоне (#FFFFFF)
| Цвет | Hex | Коэффициент | WCAG |
|---|---|---|---|
| Чёрный | #000000 | 21:1 | AAA |
| Тёмно-серый | #4B5563 | 7.6:1 | AAA |
| Средне-серый | #6B7280 | 4.6:1 | AA |
| Тёмно-синий | #1D4ED8 | 7.2:1 | AAA |
| Средне-синий | #2563EB | 5.1:1 | AA |
| Тёмно-зелёный | #047857 | 4.9:1 | AA |
| Тёмно-красный | #991B1B | 9.4:1 | AAA |
| Средне-красный | #DC2626 | 5.3:1 | AA |
На тёмном фоне (#0F172A)
| Цвет | Hex | Коэффициент | WCAG |
|---|---|---|---|
| Белый | #FFFFFF | 17.9:1 | AAA |
| Светло-серый | #E2E8F0 | 15.8:1 | AAA |
| Средне-серый | #94A3B8 | 8.3:1 | AAA |
| Светло-синий | #60A5FA | 6.2:1 | AAA |
| Светло-зелёный | #34D399 | 5.8:1 | AA |
| Светло-красный | #F87171 | 5.1:1 | AA |
Резюме
WCAG требует минимальных коэффициентов контрастности: 4.5:1 для обычного текста (AA), 7:1 для соответствия AAA и 3:1 для крупного текста и компонентов UI. Тестируйте контраст с помощью DevTools браузера или специализированных проверок контрастности. Распространённые ошибки включают светло-серый текст, фирменные цвета и текст-заполнитель. Создавайте доступные цветовые палитры с самого начала, тестируя каждый вариант цвета. Используйте более тёмные оттенки для текста на светлом фоне и более светлые оттенки для текста на тёмном фоне.
Для тестирования коэффициентов контрастности цвета и обеспечения соответствия WCAG используйте Проверку контрастности цветов. Чтобы убедиться, что ваши дизайны работают для пользователей с дальтонизмом, используйте Симулятор дальтонизма, чтобы увидеть ваш интерфейс через разные типы нарушения цветовосприятия.