~/wiki / dostupnost / kontrastnost-proverka-i-ispravlenie

Твой дизайн нечитаем для каждого 12-го мужчины. Проверь контраст прямо сейчас

Основной чат

Чат для вайбкодеров: новости, гайды, поиск исполнителей, маркетплейс и разбор реальных кейсов.

$ cd раздел/ $ join vibe dev
Твой дизайн нечитаем для каждого 12-го мужчины. Проверь контраст прямо сейчас - обложка

Откройте свой последний макет и представьте, что красный и зелёный для пользователя выглядят одинаково. Серо-коричневой кашей. Ваша кнопка «Удалить» — той же температуры, что и «Сохранить». График роста выручки — неотличим от падения. Бейдж «ошибка» — на одной волне с бейджем «успех».

Это не гипотетика и не редкий случай. Дальтонизм в той или иной форме есть примерно у каждого двенадцатого мужчины и у каждой двухсотой женщины. На аудиторию в сто тысяч мужчин — это около восьми тысяч человек, для которых ваш интерфейс может быть в лучшем случае неудобным, в худшем — опасным. И это только цветовое зрение. Добавьте сюда возрастное снижение контрастной чувствительности, людей с мигренью, тех, кто смотрит экран на солнце, бликующие OLED на улице, дешёвые офисные мониторы с убитой калибровкой — и окажется, что «нечитаемо» — это не маргинальный сценарий, а массовый.

При этом большинство макетов проходят ревью с фразой «выглядит чисто». Потому что мы смотрим на них в идеальных условиях: откалиброванный монитор, тёмная комната, свежие глаза, нормальное цветовое зрение. А продукт живёт не там.

Почему это вообще проблема дизайна, а не «особый случай»

Есть удобный миф: доступность — это про «специальных пользователей». Слепые, слабовидящие, люди с инвалидностью. Что-то отдельное, для чего есть отдельная команда, отдельный спринт и отдельный чеклист в конце квартала.

На практике контрастная слепота — это не про инвалидность. Это про то, что глаз — несовершенный сенсор, а условия использования — почти всегда плохие.

  • Человек читает приложение в метро, лицо у окна, экран в бликах.
  • Менеджер смотрит ваш дашборд через шеринг в Zoom, где цвета сжимаются кодеком.
  • Дизайнер показывает макет заказчику с проектора, у которого контраст 200:1.
  • Пользователь поставил тёмную тему ОС, а у вас приложение принудительно светлое и слегка просвечивает.

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

Что такое контраст в практическом смысле

Дизайнеры часто путают три разные вещи и называют всё это «контрастом».

  • Контраст яркости (luminance). Насколько один элемент светлее другого. Именно его измеряют WCAG и большинство плагинов. Это базовая валюта читаемости.
  • Контраст оттенка (hue). Красный против зелёного, синий против оранжевого. Выглядит «контрастно» для здорового глаза, но может полностью исчезнуть при дальтонизме или плохом мониторе.
  • Контраст насыщенности (saturation). Яркий против блёклого. Самый слабый из трёх, легко ломается на солнце и в тёмной теме.

Правило, которое стоит вбить в команду: если различие между элементами держится только на оттенке — его нет. Серьёзно, считайте, что нет. Цвет можно использовать как дополнительный сигнал, но не как единственный.

Быстрая проверка прямо сейчас

Не закрывайте этот текст, откройте свой текущий проект и потратьте две минуты.

  • Сделайте скриншот ключевого экрана и переведите его в чёрно-белый (в Figma — плагин Color Blind, в системе — фильтр «оттенки серого»).
  • Можно ли отличить активную кнопку от неактивной?
  • Видно ли, какая ссылка — ссылка, а какая — обычный текст?
  • На графиках понятно, какая линия какая, без легенды и подписей?
  • Статусы «успех / ошибка / предупреждение» различимы без цвета?

Если на любой из этих вопросов вы ответили «нет» или «не уверен» — у вас не вопрос эстетики. У вас сломанный интерфейс для заметной доли аудитории.

Анти-паттерны, которые встречаются почти везде

Это короткий список вещей, которые на ревью выглядят нормально, а в реальности тихо ломают опыт.

Цветные бейджи без иконки и текста

Зелёный кружок «онлайн», красный — «офлайн». Жёлтый «в процессе». Без подписи, без формы, без иконки. Для человека с дейтеранопией это просто три серых кружка одинаковой яркости. Лечение: добавьте либо подпись, либо форму (точка / квадрат / треугольник), либо иконку внутри.

Светло-серый текст на белом

Классика лендингов: подзаголовок цветом #B0B0B0 на белом фоне, потому что «дизайнер хотел иерархию». Иерархия появилась, читаемость ушла. На ноутбуке под солнцем такой текст исчезает полностью. Минимум для основного текста — соотношение контраста 4.5:1, для крупного — 3:1. Это не вкусовщина, это нижняя граница, ниже которой текст официально считается нечитаемым.

Графики на одном оттенке

Пять линий пятью оттенками синего. Красиво на дрибббле, бесполезно в работе. Если линии нужно различать — различайте их формой штриха, толщиной, маркерами на точках, а цвет используйте как дополнительный сигнал. То же касается пирогов и стеков из похожих цветов.

«Только цветом» в формах

Поле с ошибкой подсвечено красной рамкой. Без иконки, без текста под полем. Пользователь с дальтонизмом видит обычное поле и не понимает, почему форма не отправляется. Ошибка всегда должна быть выражена минимум двумя способами: цвет + текст, или цвет + иконка + текст.

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

Главная ошибка — думать про доступность как про финальную «галочку» перед релизом. К моменту, когда макет ушёл в разработку, переделывать палитру уже дорого: цвет влияет на токены, токены на компоненты, компоненты на десятки экранов. Контраст должен быть граничным условием на входе, а не правкой на выходе.

Хорошее правило: цвет, который не прошёл проверку, физически не должен лежать в библиотеке. Если в Figma в стилях текста есть Text/Tertiary с контрастом 2.8:1 — рано или поздно кто-то его использует под основной текст, потому что «он же в системе, значит можно».

Уровень дизайн-системы

Здесь решается 80% проблем, потому что дальше дизайнеры просто берут готовые токены.

  • Заведите явные пары «фон → текст», а не отдельные цвета. Не Gray/600, а Text/OnSurface, у которого зафиксирован контраст к Surface/Default.
  • Для каждой пары положите в описание стиля её коэффициент контраста и допустимый размер текста. Это снимает споры на ревью.
  • Состояния (hover, disabled, focus) считайте отдельно. Disabled почти всегда нарушает 3:1 — и это нормально, но тогда честно отметьте, что он не должен использоваться там, где пользователь обязан прочитать содержимое.
  • Семантические цвета (success, warning, error) дублируйте парой «цвет + иконка». В токенах храните обе сущности рядом.

Уровень макета

  • На каждом экране есть один основной слой контента. Сначала проверяйте его, потом всё остальное.
  • Любой текст поверх изображения — отдельный кейс. Затемнение, градиент-подложка или блюр не «украшение», а часть требований.
  • Полупрозрачности (rgba(0,0,0,0.6) на динамическом фоне) проверяйте на худшем варианте подложки, а не на том, что лежит в макете.

Диагностика: что и чем смотреть

Инструментов много, но реально в работе достаточно трёх режимов.

Симуляция дальтонизма

В Figma есть плагины, в Chrome — DevTools → Rendering → Emulate vision deficiencies. Прогоняйте экран через три режима: дейтеранопия, протанопия, ахроматопсия (полностью серый). Если в сером режиме интерфейс остаётся работоспособным — у вас всё хорошо.

Числовая проверка контраста

Любой контрастер (встроенный в Figma, Stark, Contrast, devtools браузера). Важно не «получить зелёную галочку», а понимать пороги:

  • 4.5:1 — основной текст, мелкие элементы UI, иконки, несущие смысл.
  • 3:1 — крупный текст (от 18pt / 14pt bold), границы интерактивных элементов, фокус-кольца.
  • 1.5–2:1 — декоративные разделители, фоновые элементы, которые не несут информации.

Реальные условия

Раз в неделю смотрите макет не только на калиброванном мониторе.

  • Откройте на телефоне на максимальной яркости и вынесите к окну.
  • Откройте на телефоне на минимальной яркости в тёмной комнате.
  • Расшарьте экран в Zoom или Meet и посмотрите глазами зрителя.
  • Распечатайте ключевой экран в чёрно-белом на офисном принтере.

Каждый из этих сценариев — реальный пользовательский кейс, а не паранойя.

Типичные ошибки на ревью

«У нас же есть тёмная тема, там всё ок»

Часто оказывается, что светлая тема прошла проверку, а тёмная — нет, потому что её делали «инверсией» в последний день. Тёмная тема — это отдельная палитра, у неё свои пары и свои контрасты. Проверяйте обе одинаково тщательно.

«Это же декоративный текст»

Слоганы в герое, цитаты, подписи под иллюстрациями — формально «декор», фактически их читают. Если текст несёт смысл, к нему применяются те же правила, что и к параграфу.

«Дизайнер согласовал у заказчика»

Заказчик одобряет на 27-дюймовом IPS с идеальным светом. Это не аргумент. Аргумент — цифры и симуляции.

«Иконка же говорящая»

Иконка без подписи понятна вам, потому что вы её рисовали. Для пользователя — нет. Если иконка несёт критичный смысл (статус, действие, ошибка), рядом должна быть подпись или хотя бы доступный aria-label, который прочитает скринридер.

Вопросы для дизайн-ревью

Прогоняйте каждый макет через этот список. Не как формальность — как диагностику.

  • Все текстовые стили в библиотеке прошли 4.5:1 или явно помечены как «крупный текст / декор»?
  • Состояния кнопок (default, hover, disabled, focus) различимы без цвета?
  • Любая ошибка в форме выражена минимум двумя способами?
  • Графики и статусы остаются читаемыми в серошкальном режиме?
  • Текст поверх картинки проверен на самой светлой и самой тёмной зоне подложки?
  • Тёмная тема прошла те же проверки, что и светлая?
  • Фокус-кольцо видно на всех фонах, где может оказаться компонент?

Если хотя бы один пункт — «не уверен», это задача, а не вкус.

Короткий итог сегмента

Доступность по контрасту дешевле всего стоит на уровне токенов и дороже всего — на уровне готового продукта. Встройте проверку в систему, держите рядом с цветом его пару и его число, и используйте симуляции как обычную часть работы, а не как ритуал перед запуском.

Когда контраст ломается в продакшене, а не в макете

Самые болезненные провалы случаются не на статичной картинке в Figma, а в живом интерфейсе: динамические данные, локализация, тёмная тема, пользовательский контент. Это уже не задача «подкрутить токен», это задача процесса. Ниже — сценарии, которые регулярно всплывают на ревью, и то, как их закрывать без героизма.

Динамический контент и UGC

Пользователь загружает аватарку, баннер, фон профиля. Дизайнер не контролирует, что именно туда придёт. Значит, поверх такого контента нельзя класть «голый» текст и рассчитывать на удачу.

Что работает:

  • Обязательная подложка под текстом: полупрозрачный слой, скрим или градиент с гарантированным контрастом против белого И против чёрного фона.
  • Минимальный размер и вес текста, который выживет на шумном фоне.
  • Запасной сплошной фон, если изображение не загрузилось или оказалось слишком ярким.

Анти-паттерн: «мы покажем красивый плейсхолдер на превью, а в проде фон будет любой». В проде — будет любой. Проверяйте на скриншоте кошачьего хвоста, а не на стоковом градиенте.

Графики, чарты, тепловые карты

Дашборд — отдельный ад. Серии данных, легенды, тултипы, сравнение периодов. Если различия только в оттенке — каждый двенадцатый аналитик не отличит «выручка» от «возвраты».

Минимальные требования:

  • Разные паттерны или формы маркеров, не только цвета линий.
  • Прямые подписи серий рядом с линией, а не только в легенде сбоку.
  • Тултипы с явным указанием серии словом, а не точкой того же цвета.
  • Палитра, протестированная в сером режиме как отдельный артефакт.

Состояния и анимации

Контраст — это не только статика. Skeleton, спиннер, прогресс, тост-уведомление, валидация в реальном времени. Каждое состояние — отдельный кейс.

  • Disabled-кнопка должна выглядеть disabled, но текст на ней всё равно остаётся читаемым — иначе пользователь не поймёт, что именно недоступно.
  • Тост на полупрозрачном фоне должен сохранять контраст и над светлым, и над тёмным контентом под ним.
  • Анимация фокуса не должна быть единственным сигналом фокуса. Уберите анимацию — кольцо должно остаться.

AI и MCP в контрастной гигиене

Сейчас всё больше команд цепляют Figma к LLM через MCP-сервер или прогоняют макеты через визуальные модели. Это работает, но не так, как кажется на первый взгляд.

Что AI делает хорошо

  • Считает контраст по выгруженным токенам и собирает отчёт по библиотеке за минуты, а не за день.
  • Находит несогласованности: один и тот же «вторичный текст» в разных компонентах с разными значениями.
  • Генерирует альтернативные палитры с заданными порогами под бренд-цвет, который менять нельзя.
  • Пишет черновик документации по парам цвет-фон, который потом руками доводит дизайнер.

Где AI стабильно ошибается

  • Не понимает контекст: считает контраст подписи к иконке как «декоративный», хотя это критичный статус.
  • Игнорирует реальную подложку под полупрозрачным слоем и считает контраст против дизайн-фона.
  • Уверенно проходит формальный порог 4.5:1 на парах, которые в дейтеранопии сливаются.
  • Хорошо звучит в ответе, но не открывает реальный прод — судит по макету, который ему скормили.

Рабочий процесс, который не разваливается

  1. AI прогоняет всю библиотеку токенов и помечает пары вне порогов.
  2. Дизайнер вручную смотрит подозрительные кейсы в контексте компонента, а не в вакууме.
  3. Симуляции дальтонизма — отдельный шаг, не доверяемый модели.
  4. Решение и обоснование фиксируются в дизайн-системе текстом, чтобы следующий запрос к AI опирался на ваши правила, а не на общие.

Главный риск автоматизации — иллюзия покрытия. Зелёная галочка от бота воспринимается как «проверено», и человек перестаёт смотреть. Договоритесь в команде, что AI-отчёт — это вход в ревью, а не его финал.

Как объяснить решение команде

Контраст часто проигрывает на встречах, потому что аргумент звучит как «по гайдлайну надо». Это слабая позиция против «зато красиво и брендово». Сильная позиция строится иначе.

Переводите в деньги и риск

  • «Этот оттенок серого не проходит на мобильном на солнце» — слабо.
  • «Каждый двенадцатый мужчина в нашей аудитории не отличит здесь статус "оплачено" от "ошибка". На объёме это столько-то обращений в поддержку» — сильно.

Не выдумывайте цифры, но связывайте контраст с конкретной болью бизнеса: поддержка, возвраты, юридический риск, тендеры, где доступность — формальное требование.

Показывайте, а не рассказывайте

На ревью не зачитывайте порог 4.5:1. Откройте симулятор и покажите экран в сером режиме рядом с оригиналом. Один скриншот «вот что видит ваш CFO с дейтеранопией» закрывает дискуссию быстрее, чем десять слайдов.

Предлагайте альтернативу, а не запрет

«Так нельзя» — тупик. «Так нельзя, но вот три варианта, которые сохраняют бренд и проходят проверку» — рабочая позиция. Заранее держите в кармане 2–3 пары, которые согласованы с бренд-командой и закрывают типовые сценарии.

Вопросы, которые стоит задать на ревью

  • Какую задачу пользователя ломает этот контраст, если ломает?
  • Что увидит человек с дейтеранопией на этом экране?
  • На каком худшем устройстве и в каких худших условиях мы это проверяли?
  • Если убрать цвет, информация остаётся?
  • Какое решение мы примем по умолчанию, когда контент будет пользовательским?

Итог сегмента

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

Чеклист перед отправкой макета в разработку

Это не финальная проверка доступности — это минимум, ниже которого макет просто не уезжает в Jira. Прогоняйте по нему каждый экран, который содержит интерактив или статус.

Базовый слой

  • Все пары текст/фон проверены на реальной подложке, а не на белом артборде
  • Текст мельче 18px проходит порог 4.5:1, крупный — 3:1
  • Иконки, несущие смысл, проходят 3:1 к фону
  • Состояния focus, hover, active, disabled проверены отдельно
  • Disabled-элементы отличимы от активных не только по цвету
  • Плейсхолдер в поле не используется как единственный лейбл

Цвет и смысл

  • Статусы (успех, ошибка, предупреждение) дублируются иконкой или текстом
  • Графики читаются в чёрно-белом виде
  • Ссылки в тексте отличаются от обычного текста не только цветом
  • Required-поля отмечены не только красной звёздочкой
  • Палитра проверена в симуляторе дейтеранопии и протанопии

Динамика и контекст

  • Текст поверх фото и видео имеет подложку, градиент или обводку
  • Кнопки на цветных баннерах проверены отдельно, а не по умолчанию из библиотеки
  • Пользовательский контент (аватары, обложки) учтён в наихудшем сценарии
  • Тёмная тема — это отдельная проверка, а не «инверсия светлой»
  • Макет посмотрен на телефоне при ярком свете, а не только на 27" мониторе

Анти-паттерны, которые регулярно проскакивают на ревью

Это не редкие случаи. Это то, что вылавливается в каждом втором продукте, если открыть его глазами человека, который смотрит на контраст осознанно.

Серый на сером ради «воздуха»

Подпись #999 на фоне #F5F5F5 выглядит элегантно в макете и нечитаема на ноуте с матовым экраном. Если хочется воздуха — добавьте отступ, а не уменьшайте контраст.

Бренд-цвет как единственный сигнал

«Активная вкладка подсвечена фирменным синим». Для человека с протанопией активной вкладки нет. Дублируйте линией, жирностью или иконкой.

Контраст «на свежий глаз»

Дизайнер смотрит на свой макет восьмой час подряд при яркости монитора 80%. Через сутки в офисе клиента при 30% яркости и солнце в окно тот же экран выглядит иначе. Проверяйте на холодную голову и на чужом устройстве.

«Поправим в разработке»

Не поправим. Разработчик подставит токен из дизайн-системы, и если в системе токен сломан — он сломан везде. Контраст лечится в источнике, а не в конкретном экране.

Тёмная тема методом инверсии

Белое стало чёрным, чёрное — белым, серые поплыли, акцентный цвет на тёмном фоне теперь жжёт глаза. Тёмная тема — это отдельная палитра с отдельными порогами, а не фильтр.

Disabled, который выглядит как нажатый

Серая кнопка с белым текстом и серая кнопка с чуть более тёмным текстом — пользователь не отличит «недоступно» от «доступно, но скучно». Минимум: иконка, курсор, тултип с причиной.

Вопросы для ревью контраста

Эти вопросы стоит задавать не только себе, но и автору макета на дизайн-критике. Они переводят разговор с «нравится / не нравится» в плоскость пользовательского сценария.

  • Где этот экран встретится с пользователем впервые: офис, метро, склад, улица?
  • Какой минимальный порог мы выбрали для этого продукта и почему именно его?
  • Что произойдёт, если пользовательский контент окажется в три раза длиннее и контрастнее, чем в макете?
  • Какие пары цветов в этом экране дублируют смысл, а какие несут его в одиночку?
  • Если завтра бренд поменяет основной цвет, какие проверки придётся прогнать заново?
  • Кто в команде последний раз открывал этот флоу в симуляторе дальтонизма?
  • В каком компоненте дизайн-системы зашита проблема, если она повторяется на пяти экранах?

Короткий практический итог

Контраст — это не вкусовая категория и не строчка из чеклиста доступности. Это про то, доходит ли смысл до человека, который смотрит на ваш экран в неидеальных условиях и не таким зрением, как у автора макета.

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

Если этот вопрос задаётся по привычке — продукт уже в другой лиге, чем большинство.

$ cd ../ ← назад к Доступность