12k
All articles

Как проверять цветовой контраст по WCAG

Проверьте контраст WCAG для текста, UI-компонентов, индикаторов фокуса и ссылок с нужными инструментами, порогами и исправлениями.

OpenReplay Team
OpenReplay Team
Как проверять цветовой контраст по WCAG

Чтобы проверить цветовой контраст по WCAG, сравните относительную яркость (relative luminance) текста переднего плана и его фона, а затем убедитесь, что полученное соотношение соответствует пороговому значению для этого типа элемента: на уровне AA это 4,5:1 для обычного текста, 3:1 для крупного текста и 3:1 для нетекстовых элементов интерфейса.

Большинство из нас усваивает это на собственном горьком опыте: выкатываем светло-серую подпись, которая отлично смотрелась на нашем мониторе, а через два спринта она проваливает аудит. Вручную это не считают — чекер выдаст результат по двум hex-значениям за секунды. В этом руководстве вы найдёте точные пороговые значения, самые быстрые способы измерить контраст, типичные ошибки, на которых спотыкается большинство команд, и правила, которые выходят за рамки основного текста и распространяются на компоненты интерфейса, индикаторы фокуса и смысл, передаваемый цветом.

Ключевые выводы

  • Уровень WCAG AA требует контраста 4,5:1 для обычного текста и 3:1 для крупного; уровень AAA поднимает эти значения до 7:1 и 4,5:1.
  • Нетекстовые элементы (границы полей ввода, контуры кнопок, значимые иконки, сегменты диаграмм и индикаторы фокуса) должны иметь контраст 3:1 относительно соседних цветов согласно WCAG 1.4.11.
  • «Крупный текст» — это 18pt (примерно 24px) или 14pt полужирный (примерно 18,66px) и больше; всё, что меньше, подпадает под порог 4,5:1 для обычного текста.
  • Самая распространённая ошибка — светло-серый основной текст: #999999 на белом даёт около 2,85:1 и не проходит, тогда как #595959 достигает 7:1 и удовлетворяет и AA, и AAA.
  • WCAG 2.2 — действующий стандарт, но минимальные требования к контрасту в нём идентичны версиям 2.1 и 2.0. Цифры не менялись.

Какой коэффициент контраста требует WCAG?

Коэффициент контраста измеряет разницу в яркости между двумя цветами. Нижняя граница — 1:1, то есть когда передний план и фон одного цвета, верхняя — 21:1, чёрное на белом. WCAG вычисляет его по формуле (L1 + 0.05) / (L2 + 0.05), где L1 и L2 — относительная яркость более светлого и более тёмного цветов. Вот пороговые значения, которые проверяет любой чекер:

ЭлементУровень AAУровень AAAКритерий успеха
Обычный текст4,5:17:11.4.3 / 1.4.6
Крупный текст3:14,5:11.4.3 / 1.4.6
Нетекстовые элементы (UI, графика, фокус)3:11.4.11

На уровне AA это означает 4,5:1 для обычного текста и 3:1 для крупного; уровень AAA поднимает ту же пару до 7:1 и 4,5:1. Что считается крупным — вопрос размера и начертания: от 18pt (примерно 24px) и выше либо от 14pt (примерно 18,66px) и выше, если текст полужирный. WebAIM Contrast Checker выдаёт результаты именно по этим порогам. Одно решающее правило покрывает большинство случаев: текст крупный? → 3:1; в остальных случаях → 4,5:1.

Миф, который стоит развеять: WCAG 2.2, опубликованный в октябре 2023 года, добавил рекомендации по внешнему виду фокуса, но не тронул минимальные требования к контрасту. Последующие версии только добавляют критерии успеха, а не переписывают уже существующие — единственным исключением стал критерий 4.1.1 Parsing, — поэтому значения 4,5:1 / 3:1 / 7:1 остаются неизменными в 2.0, 2.1 и 2.2. Низкий контраст по-прежнему остаётся самым распространённым дефектом доступности в вебе. Отчёт WebAIM Million за 2026 год обнаружил низкоконтрастный текст на 83,9% главных страниц из топ-миллиона сайтов.

Как проверить цветовой контраст?

Самый быстрый порядок действий: получить два отрендеренных hex-значения, вставить их в чекер, прочитать вердикт pass/fail. Берите именно отрендеренный цвет, а не значение из дизайн-макета: наложения, градиенты и прозрачность меняют то, что пользователь видит на самом деле.

  • WebAIM Contrast Checker: вставьте hex переднего плана и фона. Получите коэффициент и пять вердиктов, поскольку обычный и крупный текст оцениваются по AA и AAA, а нетекстовые элементы получают собственную строку для AA. Если пара не дотягивает, ползунки Lightness позволяют подкорректировать любой из цветов до прохождения, как показано в разборе инструмента от WebAIM.
  • TPGi Colour Contrast Analyser: десктопное приложение для Windows и macOS. Можно взять любой цвет прямо с экрана пипеткой, ввести значения в hex, RGB, HSV или HSL, задать альфа-канал для переднего плана и двигать ползунки, пока провальная пара не станет проходной. Также есть предпросмотр ваших цветов при восьми вариантах нарушений зрения.
  • Chrome DevTools: проинспектируйте элемент, откройте Color Picker по образцу цвета рядом с объявлением color и разверните раздел Contrast ratio. Он покажет, проходит ли пара AA и AAA, предложит кнопку Use suggested color, которая применяет проходное значение, и отрисует границы AA и AAA линиями в области оттенков, чтобы вы могли вручную сдвинуть маркер ниже них.
  • Firefox: откройте DevTools → панель Accessibility → выберите узел → посмотрите его контраст и результат проверки.

Для аудита страницы целиком используйте WAVE, axe DevTools или Lighthouse. WAVE считывает цвета текста и фона из ваших стилей и отлавливает большую часть основного текста, не дотягивающего до планки AA 4,5:1, применяя к крупному тексту более низкий порог 3:1. Чего он не может оценить — так это текст поверх изображений, альфа-композитинг, а также состояния hover и focus, поэтому важные компоненты проверяйте вручную.

Типичные ошибки контраста и как их исправить

Большинство провалов — это несколько постоянных «рецидивистов» с быстрыми и проверяемыми исправлениями.

Светло-серый текст на белом. #767676 на белом — самый светлый серый, который ещё проходит AA с показателем 4,5:1, тогда как #999 даёт лишь 2,85:1 и не проходит. Затемните основной текст до #595959, который даёт ровно 7:1 и удовлетворяет и AA, и AAA.

/* FAIL: ~2.85:1 */  color: #999999; background: #fff;
/* PASS: 7:1 */      color: #595959; background: #fff;

Текст плейсхолдеров. Задание плейсхолдерам прозрачности 40–50% — обычная причина несоответствия критерию 1.4.3, потому что фон просвечивает и опускает коэффициент ниже 4,5:1. Вместо этого задавайте реальное hex-значение #767676 или темнее. И используйте постоянно видимый <label> для всего, что пользователь обязан прочитать, поскольку плейсхолдеры исчезают при вводе.

Ссылки, выделенные только цветом. Добавьте text-decoration: underline, чтобы ссылка отличалась не только оттенком. Если убрать подчёркивание, появляется дополнительное требование: текст ссылки должен иметь контраст 3:1 относительно окружающего основного текста — вдобавок к 4,5:1, которые оба цвета обязаны обеспечить относительно фона.

Текст поверх изображений. Яркость меняется по площади фотографии, поэтому один и тот же текст проходит проверку на одном участке и проваливает на другом. Добавьте полупрозрачную подложку:

.hero {
  background:
    linear-gradient(rgba(0,0,0,.6), rgba(0,0,0,.6)),
    url("hero.jpg");
}
.hero-text { color: #fff; } /* now has guaranteed contrast */

За пределами текста: компоненты интерфейса, фокус и использование цвета

Правила контраста распространяются не только на абзацы. Критерий успеха 1.4.11 устанавливает нижнюю границу 3:1 для элементов управления и для тех частей графики, которые необходимы читателю для восприятия контента, — относительно того цвета, который находится рядом. Сюда попадают границы полей ввода, контуры кнопок, значимые иконки и серии данных на диаграммах. Состояния тоже учитываются, но с оговоркой: состояние по умолчанию должно обеспечивать 3:1, и ни одно состояние не должно опускать компонент ниже этой планки, однако эффект при наведении, который вы накладываете сверху, сам по себе не обязан соответствовать 3:1 — при условии, что он не уничтожает уже имеющийся контраст элемента управления.

Именно с индикаторами фокуса чаще всего путаются номера критериев, поэтому разложим их точно. Видимость фокуса — это 2.4.7 Focus Visible. Требование контраста 3:1 для индикатора идёт из 1.4.11 Non-text Contrast, а не из 2.4.11, который называется Focus Not Obscured (Minimum) и касается наложений, скрывающих элемент в фокусе. Критерий уровня AAA 2.4.13 Focus Appearance добавляет сверху требования к минимальному размеру и контрасту при смене состояния.

Наконец, WCAG 1.4.1 Use of Color (уровень A) означает, что цвет сам по себе никогда не должен быть единственным носителем смысла: сопровождайте красный/зелёный статус текстовой подписью или иконкой, а ссылки подчёркивайте. Одно исключение, о котором стоит помнить: неактивные (disabled) компоненты выведены из-под требований к нетекстовому контрасту и минимальному контрасту, но сохранять их читаемыми — всё равно лучший UX, чем делать их серыми до полной невидимости.

Встройте проверку контраста в рабочий процесс

Ловите проблемы с контрастом до релиза. Проверяйте на этапе дизайна плагином вроде Stark внутри Figma, а затем закрепляйте результаты в слое токенов, где для каждого цвета указан его коэффициент:

:root {
  --text-primary:   #171717; /* 18.8:1 — headings, body */
  --text-secondary: #595959; /* 7:1  — secondary text */
  --border-input:   #767676; /* 4.5:1 — meets 1.4.11 */
  --border-subtle:  #d4d4d4; /* 1.6:1 — decorative only */
}

Основной текст должен располагаться заметно выше минимума (10:1 и выше — комфортное значение), тогда как вторичный и крупный текст могут держаться на 4,5:1, а границы — на 3:1. Проверяйте восприятие при дальтонизме через Chrome DevTools → Rendering → Emulate vision deficiencies, чтобы убедиться, что смысл сохраняется и без цвета. Затем автоматизируйте: запускайте axe или Lighthouse в CI, чтобы регрессия контраста роняла сборку, а не доходила до пользователей. И отдельно прогоняйте тёмную тему: инверсия яркости ломает соотношения, которые проходили в светлой теме, поэтому пересчитывайте каждый токен для каждой темы.

Контраст — одна из самых дешёвых в исправлении проблем доступности и одна из самых простых для предотвращения. Выберите чекер, зафиксируйте пороговые значения в токенах, встройте автоматическое сканирование в CI — и перечисленные ошибки перестанут попадать в релизы. Начните прямо сегодня с аудита текущего основного текста и стилей фокуса по планкам 4,5:1 и 3:1.

Часто задаваемые вопросы

Учитывает ли контраст по WCAG оттенок и насыщенность или только светлоту?

Коэффициент контраста измеряет только относительную яркость — воспринимаемую светимость каждого цвета, — но не оттенок и не насыщенность. Именно поэтому два визуально разных цвета, например красный текст на зелёном фоне, всё равно могут не пройти проверку, если их яркость близка. Коэффициент вычисляется как (L1 + 0.05) / (L2 + 0.05) из значений яркости более светлого и более тёмного цветов, поэтому смысл, передаваемый только оттенком, регулируется отдельно — критерием WCAG 1.4.1 Use of Color.

В чём разница между WCAG 1.4.11 Non-text Contrast и 2.4.11 Focus Not Obscured?

WCAG 1.4.11 Non-text Contrast (уровень AA) требует коэффициента контраста 3:1 для компонентов интерфейса и значимой графики, включая индикатор фокуса, относительно соседних цветов. WCAG 2.4.11 Focus Not Obscured (Minimum, уровень AA), появившийся в WCAG 2.2, к контрасту отношения не имеет: он требует, чтобы элемент в фокусе не был полностью скрыт создаваемым автором контентом, например залипающими шапками или наложениями. Контраст — это 1.4.11; видимость при перекрытии — 2.4.11.

Почему один и тот же текст проходит проверку контраста в дизайн-макете, но проваливает её в браузере?

Плагины для дизайн-файлов проверяют плоские значения цветов, которые вы назначили, а браузеры компонуют итоговый отрендеренный результат. Прозрачность, полупрозрачные наложения, градиенты, фоновые изображения и режимы наложения — всё это меняет фактическую яркость, которую видит пользователь. Плейсхолдер с прозрачностью 50 процентов или текст поверх фотографии могут проходить проверку в макете и проваливать её после рендеринга. Всегда снимайте отрендеренный hex из DevTools или экранной пипетки, а не полагайтесь на исходный цвет.

Должны ли отключённые кнопки и неактивные элементы управления соответствовать минимальным требованиям WCAG к контрасту?

Нет. WCAG 1.4.3 Contrast (Minimum) прямо выводит из-под требований неактивные компоненты пользовательского интерфейса, а отключённые элементы также исключены из требования к нетекстовому контрасту 1.4.11. Это значит, что серая отключённая кнопка не провалит автоматический аудит контраста. Сохранять читаемость отключённых элементов управления всё же полезнее для юзабилити, поскольку полностью невидимые элементы сбивают пользователей с толку, но требованием соответствия WCAG для этого состояния это не является.

Digital experience platform

Truly understand users experience

See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.