Контраст цветов по WCAG: AA, AAA и APCA — полный гид 2026 года
Вы отгружаете кнопку. Фирменный оранжевый, белый текст — на вашем 4K-мониторе выглядит нормально. Аудит доступности возвращает красную отметку: коэффициент контрастности по WCAG — 1,97:1, при пороге AA 4,5:1 для основного текста. Кнопка нечитаема примерно для 220 миллионов людей с пониженным зрением по всему миру. Этот гид проводит через каждое число, которое нужно, чтобы это починить: коэффициенты WCAG 2, уровень AAA, алгоритм APCA Lc, восемь категорий нарушений цветового зрения и реализация на JavaScript, которую можно вставить в сборку.
Быстрый справочник: пороги WCAG и APCA одним взглядом
| Стандарт | Обычный текст | Крупный текст | UI / иконки | Примечание |
|---|---|---|---|---|
| WCAG AA | ≥ 4,5:1 | ≥ 3:1 | ≥ 3:1 | Юридический минимум |
| WCAG AAA | ≥ 7:1 | ≥ 4,5:1 | ≥ 3:1 | Усиленная цель |
| APCA body | Lc 75+ | Lc 60+ | Lc 45+ (иконки) | Черновик, перцептивный |
«Крупный текст» — это ≥ 18pt regular или ≥ 14pt bold (≈ 24px и ≈ 18,66px в CSS). «UI» охватывает рамки форм, фокус-кольца и любой графический объект, который пользователю необходимо различить, чтобы работать со страницей. Логотипы и чисто декоративная графика освобождены от требований к контрасту.
Что такое контраст цветов по WCAG?
Коэффициент контрастности WCAG — это числовая мера от 1:1 (нет контраста) до 21:1 (максимум), сравнивающая относительную яркость текста с яркостью фона. Web Content Accessibility Guidelines требуют ≥ 4,5:1 (AA) для основного текста и ≥ 7:1 (AAA) для усиленного соответствия.
Этот коэффициент задаёт большинство аудитов доступности. W3C опубликовал его в WCAG 2.0 в 2008 году, доработал в 2.1 (2018) и 2.2 (2023), и сегодня на него ссылаются все крупные регуляторы. ADA в США, European Accessibility Act (вступил в силу в июне 2025 года), Section 508 для федеральных ведомств США и канадский AODA де-факто используют WCAG 2.x AA в качестве нижней планки.
Зачем всё это вне юридического угла? Примерно у 220 миллионов людей по всему миру пониженное зрение, но они не слепы и читают с экрана, когда контраст шрифта и фона достаточно высок. Около 8 % мужчин и 0,5 % женщин имеют ту или иную аномалию цветового зрения. У пожилых читателей хрусталик желтеет и уменьшается раскрытие зрачка, что функционально снижает воспринимаемый контраст на 20–30 % после 60 лет. При использовании смартфона на улице ещё 20–40 % теряется из-за бликов. Страница с коэффициентом 4,5:1 на вашем столе — тот пол, при котором все эти пользователи всё ещё могут её прочитать.
Аудитория этого гида: фронтенд-инженеры, которые отгружают продакшен-UI; дизайнеры, подбирающие фирменные палитры; специалисты по доступности, проводящие аудит; команды compliance, отвечающие за юридические риски. Математика короткая. Решения, которые она навязывает, — нет.
Контраст по WCAG 2.x: математика и пороги
W3C определяет контраст в три коротких шага. Чтобы вычислить коэффициент контрастности WCAG: (1) перевести каждый цвет из gamma-encoded sRGB в линейные значения света, (2) посчитать относительную яркость с фиксированными коэффициентами чувствительности глаза к красному, зелёному и синему и (3) разделить две яркости с небольшим постоянным сдвигом, чтобы корректно обработать значения, близкие к чёрному.
Формула относительной яркости из WCAG 2.1 §1.4.3:
L = 0.2126 × R_lin + 0.7152 × G_lin + 0.0722 × B_lin
R_lin, G_lin, B_lin — линейные значения каналов после обратного разворачивания гамма-кривой sRGB. Вес 0,7152 у зелёного отражает сильную чувствительность глаза к зелёному: зелёный примерно в 7 раз «громче» синего на единицу световой энергии.
Формула коэффициента:
ratio = (L_lighter + 0.05) / (L_darker + 0.05)
Слагаемое +0,05 предотвращает деление на ноль для чистого чёрного (L = 0) и даёт максимум (1 + 0.05) / (0 + 0.05) = 21:1 для чистого белого на чистом чёрном. Минимум — 1:1, одинаковые цвета.
Ниже — реализация примерно на тридцать строк JavaScript, без зависимостей:
// sRGB hex → линейный канал света
function srgbToLinear(channel8bit) {
const v = channel8bit / 255;
return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
}
// "#RRGGBB" → относительная яркость [0, 1]
function relativeLuminance(hex) {
const h = hex.replace("#", "");
const r = parseInt(h.slice(0, 2), 16);
const g = parseInt(h.slice(2, 4), 16);
const b = parseInt(h.slice(4, 6), 16);
return (
0.2126 * srgbToLinear(r) +
0.7152 * srgbToLinear(g) +
0.0722 * srgbToLinear(b)
);
}
// Коэффициент контрастности WCAG 2.x между двумя hex-цветами
function contrastRatio(hexA, hexB) {
const lA = relativeLuminance(hexA);
const lB = relativeLuminance(hexB);
const [lighter, darker] = lA > lB ? [lA, lB] : [lB, lA];
return (lighter + 0.05) / (darker + 0.05);
}
// Пример: тёмно-сланцевый текст на белом
console.log(contrastRatio("#475569", "#ffffff").toFixed(2));
// → "7.58" — комфортно выше AA 4.5:1 и чуть выше AAA 7:1
Подставьте два hex-значения в Конвертер цветов — те же числа вернутся обратно, рядом со значением APCA Lc, классификацией гаммы и предпросмотром по восьми каналам CVD. Сами пороги конкретны:
| Элемент | AA min | AAA min | Примечание |
|---|---|---|---|
| Обычный основной текст | 4,5:1 | 7:1 | Меньше 18pt regular / меньше 14pt bold |
| Крупный текст | 3:1 | 4,5:1 | ≥ 18pt regular ИЛИ ≥ 14pt bold |
| UI-компоненты / иконки | 3:1 | — | Добавлено в WCAG 2.1 §1.4.11 в 2018 году |
| Логотипы и декор | освоб. | освоб. | Требований к контрасту нет |
На пересчёте CSS-единиц спотыкаются. 18pt = 24px при браузерном дефолте, 14pt = 18,66px. 16px-овый основной шрифт — современный стандарт — ниже порога «крупного текста», поэтому подпадает под более строгое правило AA 4,5:1. Заголовок 20px с font-weight: 700 уже считается крупным и получает более мягкие 3:1.
Один нюанс, который застаёт команды врасплох: исключение «крупного текста» в WCAG — про читаемость на крупном кегле, а не про семантику заголовков. 14px-овый <h2> не является крупным текстом — ему всё равно нужно 4,5:1. Параграф маркетингового текста 24px является крупным и получает порог 3:1. Правило завязано на отрендеренный размер в пикселях и начертание, никогда — на имя тега. Аудиторы пометят несоответствия; источник истины — ваш CSS, а не семантика HTML.
У константы +0,05 в формуле коэффициента есть конкретное происхождение: это flare term — рассеянный свет, отражённый от поверхности экрана, который поднимает видимую яркость чистого чёрного до некоторого минимального пола. Без неё OLED-пиксель, отрисовывающий настоящий чёрный на чистом белом, давал бы деление на ноль. С ней максимально достижимый коэффициент — 21:1, число, которое вы увидите выделенным в каждом инструменте доступности. Не существует физического экрана, способного выдать больше 21:1 после учёта flare, поэтому шкала WCAG там и заканчивается.
AA против AAA: какой уровень выбрать?
AA — юридический минимум; AAA — амбициозный уровень. Большинство коммерческих сайтов целятся в AA, потому что AAA вынуждает фирменные цвета сдвигаться к серой шкале, чтобы пройти, а большинство маркетинговых команд на это не идут. Решение — не «больше — лучше», а компромисс между охватом пользователей и брендовой выразительностью.
| Контекст | Рекомендуемый уровень | Почему |
|---|---|---|
| Обычный коммерческий сайт | AA | База соответствия ADA / EAA; суды цитируют WCAG 2 AA |
| Госуслуги / публичный сервис | AAA | Section 508 и аналогичные акты ЕС рекомендуют AAA |
| Здравоохранение / образование | AAA | Аудитория смещена в сторону повышенных нужд по доступности |
| Внутренний дашборд | AA | Аудитория известна, компромисс по ROI приемлем |
| Маркетинговый лендинг | AA + бренд-исключение | Фирменные цвета допустимы на герое/CTA, тело текста — AA |
Скрытая стоимость AAA вскрывается, как только вы пытаетесь провести насыщенный фирменный оранжевый через порог 7:1 на белом. Он не пройдёт. Либо вы затемняете оранжевый до того состояния, когда он перестаёт быть вашим брендом, либо принимаете AA и используете оранжевый на тёмных фонах, где он легко добивает до AAA. Многие компании целенаправленно держат AA на основном контенте и подтягивают AAA только на критичном тексте — сообщениях об ошибках или юридических уведомлениях.
Регуляторы не стали ждать распространения AAA. Регламент ADA по веб-доступности 2024 года ссылается на WCAG 2.1 AA. European Accessibility Act, обязательный к исполнению с июня 2025 года, требует WCAG 2.1 AA по всем подпадающим цифровым сервисам. Section 508 федерального правительства США использует WCAG 2.0 AA в качестве базовой линии (с рекомендацией AAA там, где это осуществимо). Канадский AODA ссылается на WCAG 2.0 AA. Везде одно: AA — планка, AAA — цель.
APCA: новый перцептивный алгоритм
APCA — Advanced Perceptual Contrast Algorithm, разработанный Эндрю Сомерсом под маркой Myndex, — это кандидат-алгоритм для WCAG 3. Он заменяет симметричный коэффициент WCAG 2 на полярно-знаковую оценку Lc от −108 до +108, где знак сообщает, в каком направлении идёт контраст (тёмный текст на светлом против светлого текста на тёмном), а величина отражает воспринимаемый контраст на реальном излучающем экране.
APCA важен потому, что симметричная формула WCAG 2 пропускает два реальных эффекта:
- Асимметрия полярности. Светлый текст на тёмном фоне читается иначе, чем тёмный текст на светлом, даже при одинаковом коэффициенте WCAG. WCAG 2 возвращает одно и то же число в обоих направлениях; APCA — нет.
- Моделирование дисплея. Формула WCAG 2 была выведена из моделей яркости печатной бумаги. APCA настроена под sRGB-дисплеи в типичном офисном освещении, что ближе к тому, что реально видят пользователи.
Компромисс: APCA сложнее (содержит экспоненты, чувствительные к полярности, и поправки на начертание шрифта) и пока не является регуляторным стандартом. Анализ Адриана Розелли от апреля 2026 года описывает текущее положение APCA: алгоритм технически перспективный, но сам WCAG 3 находится на ранних черновиках в треке Silver, и APCA пока не утверждён в качестве официального алгоритма.
Bronze-пороги APCA (практический пол, на который целится большинство команд) выглядят так:
| Сценарий | Рекомендуемый Lc | Минимум Lc |
|---|---|---|
| Основной текст (16px, weight 400) | 90+ | 75 |
| Крупный текст (24px, weight 400) | 75+ | 60 |
| UI-элементы и нетекстовые иконки | 60+ | 45 |
| Метки / placeholder | 30+ | 30 |
APCA интересен (и Конвертер цветов показывает обе метрики бок о бок) из-за случаев, где он расходится с WCAG 2:
#FFA500(оранжевый) на#FFFFFF: WCAG 2 выдаёт 1,97:1 — явный провал по AA. APCA соглашается, оценка около Lc 38, — тоже провал. Оба алгоритма говорят «нет», но в продакшене это сочетание всё равно встречается с обоснованием «выглядит нормально».#767676(средний серый) на#FFFFFF: WCAG 2 выдаёт 4,54:1 — чуть выше AA 4,5:1, формально проход. APCA оценивает эту пару примерно в Lc 60, что ниже Bronze-порога APCA 75 для основного текста. WCAG проходит; APCA — нет. Реальный пользовательский опыт ближе к вердикту APCA: серый на белом труднее читать на размере основного текста, чем подсказывает коэффициент.#3b82f6(Tailwind blue-500) на#000000: WCAG 2 выдаёт 5,71:1 — комфортный проход AA. APCA оценивает это примерно в Lc 65 — ниже минимума Lc 75 для основного текста. Светло-синий текст на тёмном фоне, любимый паттерн тёмной темы, — каноничный случай «WCAG проходит, APCA сигналит».
Стороны выбирать не обязательно. Рабочая позиция в большинстве продакшен-команд: держать WCAG 2 AA как регуляторную базу, потому что именно по нему проверяют compliance-аудиты, и параллельно прогонять APCA как проверку «а это вообще читаемо?» — особенно для тёмных тем и насыщенных фирменных цветов. Конвертер цветов показывает оба числа в одной строке, чтобы не приходилось переключаться между чекерами.
Дальтонизм и за пределами контраста
Коэффициенты контрастности — это только половина цветовой доступности. Около 8 % мужчин и 0,5 % женщин видят цвета не так, как учебный трихромат, — и самый распространённый вариант, дейтераномалия, попадает ровно в середину красно-зелёной пары, которую мы повсюду используем для состояний success/error. WCAG 1.4.1 («Использование цвета») прямо запрещает делать цвет единственным носителем информации; именно это правило здесь и работает.
Полная таксономия различий в цветовом зрении делится на три группы: дихромазия (одна колбочка отсутствует), аномальная трихромазия (одна колбочка смещена) и редкие монохромазии.
| Тип | Бытовое название | Затронутый канал | Распространённость (М / Ж) |
|---|---|---|---|
| Protanopia | Красная слепота | L-колбочка отсутствует | 1,0 % / 0,01 % |
| Deuteranopia | Зелёная слепота | M-колбочка отсутствует | 1,1 % / 0,01 % |
| Tritanopia | Синяя слепота | S-колбочка отсутствует | 0,003 % / 0,003 % |
| Protanomaly | Красная аномалия | L-колбочка смещена | 1,3 % / 0,02 % |
| Deuteranomaly | Зелёная аномалия | M-колбочка смещена | 5,0 % / 0,4 % |
| Tritanomaly | Синяя аномалия | S-колбочка смещена | 0,01 % / 0,01 % |
| Achromatopsia | Без цвета | Все колбочки отсутствуют | 0,003 % (очень редко) |
| Cone monochromacy | Частичный серый | Только одна колбочка | 0,001 % |
Одна только дейтераномалия — это 5 % мужчин, один из двадцати. Это та аудитория, которая видит красный индикатор ошибки и зелёный индикатор успеха почти как одинаковый оливково-коричневый оттенок. Исправление — не переделывать всю цветовую систему; нужно добавить второй канал. Красная иконка ошибки в паре с формой «×» и словом «Ошибка» переживает любой вариант из таблицы. Голая красная точка — нет.
Симуляция CVD в коде использует два стандартных набора матриц: Brettel–Viénot–Mollon (1997) для дихромазий и Machado–Oliveira–Fernandes (2009) для аномальных трихромазий. Подход Brettel проецирует входной цвет на плоскость, натянутую на отклики двух оставшихся колбочек; Machado параметризует сдвиг колбочки по степени тяжести. Оба реализуются как SVG-фильтры или CSS-матрицы. Конвертер цветов включает все восемь вариантов в виде превью одной кнопкой — можно прогнать фирменный цвет по всему спектру, не покидая страницу.
Короткий SVG-фильтр — добавьте на страницу и сошлитесь по id — даёт встроенную в браузер симуляцию протанопии для быстрого тестирования:
<svg style="display: none">
<filter id="protanopia">
<feColorMatrix type="matrix" values="
0.567 0.433 0.000 0 0
0.558 0.442 0.000 0 0
0.000 0.242 0.758 0 0
0.000 0.000 0.000 1 0"/>
</filter>
</svg>
<style>
.preview-protanopia { filter: url(#protanopia); }
</style>
Примените .preview-protanopia к контейнеру страницы — и увидите то, что видит протаноп. Повторите с матрицами дейтеранопии и тританопии (их коэффициенты задокументированы в работе Brettel и включены в большинство библиотек CVD-симуляторов). В Chrome DevTools панель Rendering имеет встроенные симуляторы под пунктом «Emulate vision deficiencies» — полезны для быстрой проверки, менее удобны для съёма скриншотов в CI.
Глубинное правило, за пределами симуляции: никогда не позволяйте цвету быть единственным отличием между двумя состояниями. Иконки должны отличаться формой (× против ✓), состояния — текстовой подписью («Ошибка» против «Успех»), категории — узором (сплошной против штриховки). Цвет — это множитель к другим сигналам, а не их замена.
Есть класс провалов, которые чекеры контраста не ловят, а CVD-симуляторы ловят. Сегменты круговой диаграммы, различимые только по оттенку, легенды карт, цветом кодирующие страны, статусные плашки на градиенте зелёный/жёлтый/красный — все они могут пройти WCAG 2 на контрасте против фона, оставаясь нечитаемыми для дейтеранопа, который сравнивает их между собой. Правило: проверять различимость между соседними цветами в самом дизайне, а не только против окружающего холста. Два сегмента slate-500 рядом на одинаковой светлоте неразличимы независимо от поворота оттенка. Добавьте шаг по яркости между соседними областями — и диаграмма переживёт любой вариант CVD.
Ахроматопсия и колбочковая монохромазия редки, но их стоит закладывать в дизайн явно, потому что они схлопывают все различия по оттенку. Человек с ахроматопсией воспринимает только яркость — ваш цветокодированный UI выглядит для него как чёрно-белая фотография. Если дизайн выдерживает filter: grayscale(1) поверх всей страницы (попробуйте в DevTools), вы прошли самую строгую версию правила «цвет — не единственный сигнал». Это самый дешёвый тест на доступность, и он обычно вскрывает несколько провалов сразу после включения.
Аудит палитр Tailwind и Material
Большая часть фронтенд-работы использует готовую палитру: Tailwind v4, Material 3, Radix или shadcn. Вопрос доступности превращается в «на какой ступени этой рампы текст становится читаемым?» — и ответ ближе к эмпирическому правилу, чем к тому, что обычно пишут в документации.
Для slate-рампы Tailwind v4 на чисто белом числа WCAG и APCA выглядят так:
| Tailwind class | Прибл. hex | WCAG к белому | AA body | AAA body | APCA Lc (прибл.) |
|---|---|---|---|---|---|
| slate-400 | #94a3b8 | 2,56:1 | ✗ | ✗ | ~38 ✗ |
| slate-500 | #64748b | 4,76:1 | ✓ | ✗ | ~60 ✗ body |
| slate-600 | #475569 | 7,58:1 | ✓ | ✓ | ~78 ✓ body |
| slate-700 | #334155 | 10,35:1 | ✓ | ✓ | ~90 ✓ body |
Практические правила, которые из этого вытекают:
- Основному тексту нужен slate-600 или темнее. Slate-500 проходит WCAG AA, но не дотягивает до порога APCA для основного текста — то есть формально соответствует, но неудобен. Slate-600 — безопасный пол.
- UI-подписи и вторичный текст могут использовать slate-500. UI-компонентам нужно всего 3:1; 4,76:1 у slate-500 — комфортно, а текст обычно сопровождается визуальным контекстом.
- Placeholder можно делать на slate-400 или светлее. Текст placeholder исключён из WCAG 1.4.3 как декоративный только если над полем сохранена видимая подпись. Паттерн «inline-label-as-placeholder» обязан добивать до порога основного текста.
- Чистый чёрный на slate-100 / slate-200 — выброшенные чернила. Вы уже на 17:1+; имеет смысл взять slate-700 или slate-800 как цвет текста ради более мягкого ощущения без потери читаемости.
Material 3 использует похожую структуру тональной палитры. Его surface-container-high живёт около тона 92 (очень светлый); его on-surface — около тона 10 (близко к чёрному). Контраст между любым on-surface и любым surface-* токеном в одном семействе гарантированно проходит AA по спецификации Material. Не сочетайте on-surface-variant (тон 30) с surface-container (тон 94), не проверив — это реальный промах, который я видел в продакшене.
Если у вас уже есть палитра, которая проваливает контраст, OKLCH даёт самый чистый путь починки. Вместо того чтобы вслепую двигать hex-коды, переведите цвет в OKLCH, зафиксируйте C (chroma) и H (hue) и снижайте L (lightness), пока контраст не пройдёт. Поскольку канал L в OKLCH действительно перцептивный, узнаваемость бренда остаётся, а контраст подтягивается. Инструмент HEX в OKLCH делает это преобразование в один шаг; статья-сосед OKLCH: объяснение цветового пространства разбирает математику подробно.
Тёмной теме нужен отдельный абзац. Симметричный коэффициент WCAG 2 по определению проходит одни и те же сочетания и в светлой, и в тёмной теме. APCA, чувствительный к полярности, регулярно помечает основной текст в тёмной теме как менее читаемый, чем тот же hex-пара в светлой. Светлое на тёмном всегда теряет часть воспринимаемого контраста по сравнению с тёмным на светлом при одном и том же численном значении — это известный эффект адаптации глаза. Прогоняйте APCA на каждой паре для тёмной темы перед выпуском.
Чекеры контраста и CI-процессы
У дизайнеров и инженеров — свой любимый чекер; практический вопрос в том, какая комбинация инструментов сшивается в реальный процесс. Вот картина на 2026 год:
| Инструмент | WCAG 2 | APCA | CVD sim | Аудит палитры |
|---|---|---|---|---|
| WebAIM Contrast Checker | ✓ | ✗ | ✗ | ✗ |
| Adobe Color | ✓ | ✗ | ✓ | ✓ |
| Stark (Figma plugin) | ✓ | ✓ | ✓ | ✓ |
| Polypane (браузер) | ✓ | ✓ | ✓ | ✓ |
| Chrome DevTools color picker | ✓ | ✓ (эксп.) | ✗ | ✗ |
| axe DevTools | ✓ | ✗ | ✗ | ✓ (на уровне стр.) |
| Go Tools Color Converter | ✓ | ✓ | ✓ (8 типов) | ✓ (Tints/Shades) |
Процесс, выдерживающий реальное продуктовое давление, выглядит так:
- В Figma дизайнеры прогоняют Stark по каждому фрейму, чтобы рано всплывали проваленные пары. Stark отлавливает очевидных нарушителей ещё до того, как hex-код попадает в кодовую базу.
- На передаче hex-кодов инженеры вставляют значение в Конвертер цветов, чтобы получить коэффициент WCAG + APCA Lc + классификацию гаммы + CVD-превью в одной строке. Если пара — тёмная тема или насыщенный фирменный цвет, парная метрика ловит случаи «WCAG проходит, APCA нет», которые Stark может пропустить.
- На этапе PR
axe-core/playwrightсканирует собранные страницы на любые нарушения контраста на отрисованном DOM, включая динамические состояния. Это ловит фокус-кольца, hover-состояния и disabled-аффордансы, которые статические дизайн-файлы пропускают. - В QA панель Rendering в Chrome DevTools симулирует протанопию/дейтеранопию/тританопию для точечных проверок критичных потоков. Color Picker в DevTools также показывает коэффициент WCAG прямо при наведении на элемент.
Pa11y, Lighthouse CI и @axe-core/playwright — все они выставляют ассерты на контраст как часть более широких аудитов доступности. Никто из них на сегодня не проверяет APCA; все проверяют WCAG 2. Реалистичный компромисс — «загонять WCAG 2 AA в CI, а APCA Lc проверять вручную как sanity check для фирменных цветов и тёмной темы».
Полезный паттерн из практики дизайн-систем: встройте проверку контраста в шаг валидации токенов, а не только в QA уровня страницы. Если ваши дизайн-токены компилируются из исходного файла (JSON, YAML или модуля TypeScript), добавьте скрипт, который перебирает каждую пару --text-* × --surface-*, разрешённую системой, и проверяет минимальный коэффициент WCAG. Скрипт отрабатывает за миллисекунды, ловит регрессии при правке значения токена и выдаёт матрицу контраста, которая заодно служит документацией для дизайн-команды. Проверка не зависит ни от одной отрендеренной страницы — она работает чисто на токенах, поэтому ловит провал до того, как UI отгружен.
Для разовых преобразований по ходу процесса — конвертации между hex, RGB, HSL и OKLCH во время отладки — спицы HEX в RGB, HEX в HSL, HEX в OKLCH и RGB в HEX покрывают круговые переходы в любой формат цвета, который ожидает ваш тулчейн.
Частые ошибки и как их исправить
После лет аудитов доступности всплывают одни и те же шесть провалов. У каждого — аккуратное решение:
-
Placeholder светло-серым.
#999999на белом — 2,85:1, не проходит AA. Либо углубить до#666666(5,74:1, проходит AA), либо — лучше — заменить паттерн «placeholder-как-label» постоянной видимой подписью над полем. Placeholder не должен нести информацию. -
Кнопка фирменного оранжевого с белым текстом.
#FFA500на белом — 1,97:1, провал AA с большим запасом. Исправление, сохраняющее бренд, — инвертировать направление контраста: тёмный текст (например,#451a03) на оранжевом фоне или оставить белый текст, но затемнить кнопку до глубокого насыщенного коричнево-оранжевого. Перепроверьте в Конвертере цветов перед отгрузкой. -
Яркая синяя ссылка в тёмной теме.
#3b82f6на#000000— 5,71:1, WCAG AA проходит, но APCA Lc ≈ 65, ниже порога Lc 75 для основного текста. Возьмите OKLCH и поднимите L с ≈ 0,63 до 0,75, удерживая C и H — окажетесь около#7aa5f8с комфортным APCA Lc 80+ и тем же оттенком. -
Текст в
disabled-состоянии цвета#CCCCCC. 1,61:1 к белому. WCAG 1.4.3 освобождает чисто декоративный текст от правила коэффициента, но disabled UI-контролы — не декоративны: они сообщают «сейчас недоступно». Сопроводите приглушённый цвет неколорным сигналом (зачёркивание, иконка замка, tooltip «Недоступно»), чтобы пользователь с CVD или пониженным зрением всё равно понял состояние. -
Статусные иконки, различающиеся только оттенком. Красный
×и зелёная✓— нормально, потому что форма уже различает их. Красная точка против зелёной — нет. Используйте форму и цвет вместе — превью CVD в Конвертере цветов делает провальный случай очевидным за секунду. -
Текст поверх градиентного фона. Градиент от
#3b82f6к#a78bfaпротив белого текста проходит контраст в середине и проваливает у лавандового края. Исправление — проверять контраст по худшей точке градиента или класть полупрозрачную тёмную подложку, чтобы эффективная яркость фона всегда оставалась ниже известного порога.
Каждая правка занимает минуты. Аудит-цикл, который они предотвращают, занимает недели.
FAQ
Что такое контраст WCAG AA?
WCAG AA требует ≥ 4,5:1 между основным текстом и фоном или ≥ 3:1 для крупного текста (≥ 18pt regular или ≥ 14pt bold) и UI-компонентов вроде рамок форм. AA — юридическая база по ADA, EAA и Section 508 — большинство коммерческих сайтов целятся в AA, потому что он закрывает регуляторную планку, не вынуждая фирменные цвета сдвигаться к серой шкале.
Какой коэффициент контрастности нужен для AAA?
WCAG AAA требует ≥ 7:1 для обычного основного текста и ≥ 4,5:1 для крупного текста. AAA рекомендован для медицинских, образовательных и государственных сайтов, где аудитория смещена к повышенным нуждам по доступности. Фирменным цветам часто приходится плющиться к околосерым значениям, чтобы пройти AAA, — поэтому многие коммерческие продукты останавливаются на AA.
Что такое APCA, и это WCAG 3.0?
APCA (Advanced Perceptual Contrast Algorithm), разработанный Эндрю Сомерсом / Myndex, — это кандидат-алгоритм в рамках проекта WCAG 3 Silver. Он использует чувствительные к полярности оценки Lc от −108 до +108 вместо симметричных коэффициентов. По состоянию на 2026 год WCAG 3 всё ещё находится в раннем черновике, и APCA формально не утверждён — регуляторным стандартом, который надо соблюдать сегодня, остаётся WCAG 2.1 / 2.2 AA.
Помогает ли тёмная тема доступности контраста?
Иногда — но не автоматически. Симметричный коэффициент WCAG 2 проходит одни и те же сочетания и в светлой, и в тёмной теме, но APCA (чувствительный к полярности) часто помечает основной текст тёмной темы как менее читаемый, чем та же hex-пара в светлой. Перед отгрузкой всегда перепроверяйте тёмную тему и через WCAG, и через APCA; светлое-на-тёмном теряет воспринимаемый контраст так, как симметричный коэффициент увидеть не может.
Почему мой фирменный цвет проваливает WCAG AA?
У насыщенных цветов средней яркости — большинства оранжевых, жёлтых, лаймовых, светло-синих — значения относительной яркости слишком близки к белому, чтобы добить до 4,5:1. Решение: сохранить фирменный оттенок для акцентов и крупных заголовков, а основной текст сочетать с более тёмным тоном из того же семейства оттенков. Используйте OKLCH, чтобы понизить канал L, не смещая оттенок, — Конвертер цветов находит ближайший проходной оттенок в один шаг.
Совместимы ли коэффициенты WCAG 2 и оценки APCA?
Нет. WCAG 2 возвращает симметричный коэффициент (1–21); APCA возвращает полярно-знаковую оценку Lc (от −108 до +108). Связь нелинейна: пара 4,5:1 по WCAG может получить Lc 60 или Lc 75 в APCA в зависимости от того, какой цвет сверху. Считайте их двумя независимыми проверками, а не переводами друг друга.
Можно ли применять контраст к маленьким UI-иконкам?
Да, с оговорками. WCAG 2.1 §1.4.11 требует ≥ 3:1 для UI-компонентов и графических объектов. Для декоративных иконок в паре с видимой текстовой подписью требования к контрасту смягчаются — смысл несёт подпись. Для самостоятельных иконок (например, лупа поиска без подписи) держите полные 3:1 относительно окружающего фона.
Как протестировать дальтонизм без отдельной симуляции?
Используйте Chrome DevTools → Rendering → «Emulate vision deficiencies» для протанопии, дейтеранопии, тританопии и ахроматопсии. Сочетайте с 8-канальным CVD-превью в Конвертере цветов для вариантов аномальной трихромазии (дейтераномалия — самый частый случай, 5 % мужчин). Для отчёта по аудиту снимайте скриншоты под каждой симуляцией, чтобы рецензенты видели режимы провала прямо в тексте.
Заключение
Пять выводов из всего гида:
- AA 4,5:1 — юридический пол. Добейтесь его для всего основного текста или ждите шума по compliance.
- AAA 7:1 — для здравоохранения, образования и госсектора. Большинство коммерческих брендов сознательно останавливаются на AA.
- APCA Lc — sanity check на реальную читаемость. Запускайте параллельно с WCAG 2, особенно для тёмной темы и насыщенных фирменных цветов.
- Цвет никогда не должен быть единственным сигналом. Сопровождайте любой цветовой знак формой, текстом или узором — одна только дейтераномалия — это 5 % мужской аудитории.
- Канал L в OKLCH — правильная ручка. Когда цвет не проходит контраст, снижайте L (а не S и не B), чтобы починить без сдвига оттенка.
Подставьте любые два hex-кода в Конвертер цветов, чтобы увидеть коэффициент WCAG, APCA Lc, классификацию гаммы и 8-канальное CVD-превью бок о бок. Этот единый вид заменяет шесть отдельных инструментов и быстрее всего закрывает аудиты, которые описывает этот гид.