~/wiki / dostupnost / wcag-3-i-ai-generatsiya-proverka-dostupnosti

WCAG 3.0 и AI-генерация: как проверять доступность того что нарисовал не ты

Основной чат

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

$ cd раздел/ $ join vibe dev
WCAG 3.0 и AI-генерация: как проверять доступность того что нарисовал не ты - обложка

Дизайнер открывает Figma-файл, который сгенерировал ему ассистент. Лендинг, дашборд, флоу онбординга — всё уже расставлено. Сетки сходятся, тени мягкие, состояния кнопок есть. Выглядит нормально. Уходит в разработку.

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

Это новая реальность. Часть интерфейса теперь создаёт не человек, а модель — Figma AI, v0, Lovable, кастомные MCP-агенты, плагины поверх дизайн-системы. Они быстро собирают композицию, но почти ничего не знают про доступность. А WCAG 3.0 (даже на стадии working draft) поднимает планку — там уже не «контраст 4.5:1 и всё», там оценка по задачам, по контекстам использования, по нескольким группам пользователей сразу. Проверять это глазами больше не получится.

Почему старый подход к доступности больше не работает

Раньше схема была простая: дизайнер сам поставил контраст, сам подписал alt, сам подумал про tab order. Доступность встроена в процесс, потому что у процесса один автор.

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

Отсюда три новых типа ошибок, которых почти не было в ручном дизайне:

  • Правдоподобная, но фиктивная семантика. Кнопка нарисована как кнопка, но это div с onClick. Заголовок выглядит как H2, но размечен как обычный текст.
  • Контраст «на глаз». Модель подбирает оттенки так, чтобы было красиво, и регулярно промахивается на 0.3–0.7 по APCA. Глазом не видно, скринридер переживёт, а пользователь со слабым зрением — нет.
  • Состояния, которых нет. Сгенерирован default и hover. Focus-visible, disabled, loading, error, empty — отсутствуют или одинаковые. WCAG 3.0 на это смотрит отдельно.

Что меняется в WCAG 3.0 по сравнению с 2.x

Коротко и без занудства, потому что от этого зависит чеклист.

От бинарного «прошёл/не прошёл» к шкале

В 2.x критерий либо выполнен, либо нет. В 3.0 — оценка по шкале (рейтинги вроде bronze/silver/gold в ранних драфтах). Это значит, что нельзя больше «закрыть строчку галочкой». Нужно показывать, насколько хорошо решена задача, а не просто факт её решения.

Для AI-генерации это критично: модель выдаёт результат, который часто формально «не нарушает», но по качеству — на нижней границе. Это надо ловить.

Оценка по результатам, а не по технике

WCAG 3.0 смотрит, может ли пользователь выполнить задачу — найти товар, оплатить, написать сообщение. Не «есть ли alt у картинки», а «понятен ли смысл блока без зрения».

Это плохо стыкуется с тем, как работают AI-инструменты. Они генерируют экран, а не сценарий. Они не знают, что пользователь должен в итоге сделать. Значит, ответственность за сценарную проверку полностью на вас.

Контраст по APCA, а не по WCAG 2 формуле

В 3.0 двигаются к APCA — алгоритму, который учитывает реальную воспринимаемую разницу, размер и вес шрифта. Многие пары цветов, которые проходили 2.x, по APCA выглядят слабо, особенно тонкие шрифты на цветных фонах. AI любит именно такие сочетания — они «дизайнерские».

Первый фильтр: что проверять до того, как макет ушёл в разработку

Пока всё свежо и переделать дёшево. Это не полный аудит, это входной контроль — 15–20 минут на экран.

Чеклист входного контроля AI-макета

  • У каждого интерактивного элемента понятно, что это интерактив (не только по цвету)
  • Есть состояния: default, hover, focus-visible, active, disabled, loading
  • Focus-visible отличается от hover и виден на всех фонах, где элемент встречается
  • Контраст текста проверен по APCA, а не только по WCAG 2 (особенно для размеров меньше 16px и тонких начертаний)
  • Цвет не единственный носитель смысла (ошибки, статусы, ссылки в тексте)
  • Иконки без подписи имеют осмысленную текстовую альтернативу в спецификации
  • Размер тач-таргета — минимум 24×24, целевой — 44×44, с зазорами
  • Текстовые блоки не зашиты картинкой
  • Порядок чтения совпадает с визуальным порядком (проверяется в Figma через outline/layers)
  • Любая анимация длиннее 0.2 с имеет внятный смысл и не зациклена

Анти-паттерны, которые AI генерирует особенно охотно

  • Серый плейсхолдер вместо лейбла — поле без подписи, при вводе подпись пропадает.
  • «Призрачные» кнопки — контур 1px цветом #D0D0D0 на белом. По APCA это почти невидимо.
  • Двухцветные графики без подписи значений — смысл считывается только зрением и только в цвете.
  • Тосты-уведомления, которые исчезают через 2 секунды без возможности вернуться.
  • Модалки без явного заголовка как dialog и без возврата фокуса на триггер.

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

Рабочий процесс: где в пайплайне ловить проблемы

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

Четыре чекпоинта на пути от промпта до релиза

  • Промпт. До генерации задать модели рамки: размер тач-таргетов, обязательные состояния, контрастные пары из дизайн-системы, ограничения по плотности. Не «сделай красиво и современно», а «компонент должен иметь focus-visible 2px outside, hover, disabled с opacity 0.5 не использовать».
  • Выход модели. Входной контроль из предыдущего раздела. 15 минут на экран, до того как макет ушёл в Figma как «принято».
  • Сборка в макет. Когда AI-кусок встаёт в реальный экран с реальными данными — длинные имена, пустые состояния, ошибки сети, RTL. Здесь всплывает половина проблем, которые на изолированной картинке были не видны.
  • Спецификация для разработки. Передача не картинки, а намерения: какая семантика, какие ARIA-атрибуты, какой порядок фокуса, какие тексты для скринридера. Иначе фронт получит «div, который выглядит как кнопка», и так и сверстает.

Кто за что отвечает

Частая ошибка — считать, что раз макет сгенерировала модель, то и доступность «как-то сама». Нет. Ответственность остаётся на человеке, и её полезно проговорить вслух.

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

Если в команде нет человека, который явно владеет этим участком, AI-макеты будут уезжать в прод с одинаковыми болячками месяц за месяцем.

Диагностика: как быстро понять, насколько плохо

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

Тест за пять минут

  1. Пройдите экран только клавишей Tab. Видно ли, где фокус? Логичен ли порядок?
  2. Включите серую шкалу в системе. Различимы ли статусы, ошибки, активные состояния?
  3. Уменьшите шрифт до 200% через зум браузера или симуляцию в Figma. Не ломается ли вёрстка, не обрезается ли текст?
  4. Прочитайте экран вслух как будто диктуете другу по телефону. Понятна ли структура без визуала?
  5. Спросите себя: что произойдёт, если поле ввода вернёт ошибку? Есть ли в макете этот стейт?

Если на любом из шагов спотыкаетесь — макет не готов, независимо от того, насколько он красивый.

Где смотреть APCA, а не WCAG 2

WCAG 2-калькуляторы встроены во все плагины Figma и дают зелёную галочку слишком щедро. Для тонких шрифтов, светлого текста на цветных фонах и любых градиентов лучше прогонять через APCA-калькулятор отдельно. Целевые значения для основного текста — Lc 75+, для крупных заголовков — Lc 60+, для неактивных и декоративных элементов — Lc 45+. Это грубые ориентиры, но они спасают от «формально проходит, читать невозможно».

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

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

  • Какой сценарий решает этот экран и где в нём пользователь со скринридером?
  • Что является primary action и почему он визуально отличается от secondary?
  • Где здесь focus-visible и совпадает ли он с hover?
  • Какие состояния не нарисованы и почему — их не будет в продукте или о них забыли?
  • Если убрать цвет, остаётся ли смысл?
  • Что увидит разработчик в спецификации: компонент с семантикой или картинку?
  • Что произойдёт с этим экраном на 320px по ширине и при 200% зуме?
  • Какие тексты пойдут в aria-label и кто их пишет — дизайнер или фронт по наитию?

Хорошее ревью — это не «нашёл косяк», а разговор, после которого автор сам видит, чего не хватает.

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

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

Продвинутые сценарии: когда AI становится частью пайплайна

Одиночный макет — это половина истории. Реальная боль начинается, когда AI встроен в ежедневный процесс: генерация вариантов через Figma AI, импорт компонентов из v0, передача макета в Cursor через MCP. Здесь доступность ломается не на уровне отдельного экрана, а на уровне привычки.

Сценарий 1: «Сделай мне 5 вариантов этой карточки»

Модель честно отдаёт пять. Все красивые, ни один не помечен по контрасту, у трёх неактивные состояния сделаны через opacity: 0.4 поверх и без того блёклого цвета. Дизайнер выбирает «самый чистый», и в библиотеку едет компонент, который не пройдёт даже WCAG 2.

Что помогает:

  • Прогонять все варианты через APCA-плагин до выбора, а не после.
  • В промпте сразу фиксировать: «disabled через токен --state-disabled, не через opacity».
  • Держать в дизайн-системе референсные значения Lc и сравнивать с ними, а не «на глаз».

Сценарий 2: MCP-передача в код

Figma MCP отдаёт модели не картинку, а структуру: фреймы, autolayout, имена слоёв. Если у вас слой называется Group 47, в код приедет <div>. Если называется Button / Primary / Disabled — есть шанс на семантику, но только шанс.

Антипаттерн: считать, что MCP «сам разберётся». Не разберётся. Он перенесёт ровно то, что вы заложили в имена и структуру.

Что закладывать в макет, чтобы выход в код был осмысленным:

  • Имена компонентов через категории: Input / Text / Error, а не Frame 12.
  • В описание компонента — роль и aria-label по умолчанию.
  • Состояния как варианты компонента, а не как отдельные фреймы рядом.
  • Текст-плейсхолдеры, которые не выглядят как настоящие подписи (иначе модель решит, что это лейбл).

Сценарий 3: AI-ревью AI-макета

Соблазн прогнать сгенерированный экран через ту же модель с промптом «найди проблемы доступности». Иногда работает, чаще — нет. Модель уверенно перечислит общие пункты («проверьте контраст», «добавьте alt-тексты»), но не увидит, что конкретно в этом макете focus-trap не закрывается с клавиатуры. AI-ревью полезно как первый фильтр, но не как финальная проверка.

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

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

Переводите на язык собеседника

  • Продукту: «этот экран теряет N% сценариев на скринридерах, и это аудитория, которая не уйдёт сама — она просто не сконвертируется».
  • Разработчику: «если мы сейчас зашьём div onClick, через спринт придётся переписывать на button, потому что фокус не работает».
  • Юристу или комплаенсу (если есть): «EAA с 2025 года в ЕС требует доступности для коммерческих продуктов — это не nice to have».

«Слепые пользователи» как аргумент работает плохо. «Стоимость переделки» и «риск» — лучше.

Делайте проблему видимой

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

Чеклист качества AI-макета перед мержем

  • Все интерактивные элементы — компоненты с состояниями, а не статичные фреймы.
  • Контраст проверен по APCA, а не только по WCAG 2.
  • Focus-visible нарисован и отличается от hover.
  • Ошибки и пустые состояния есть в макете, не «доделаем потом».
  • Тексты для ассистивных технологий прописаны в спецификации, а не оставлены на разработчика.
  • Порядок чтения совпадает с визуальным порядком — проверено Tab-навигацией в прототипе.
  • Имена слоёв и компонентов осмысленные — на случай передачи через MCP или экспорта в код.

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

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

Финальный чеклист: что проверять руками

Предыдущий чеклист был «макро» — про то, что вообще должно быть в макете. Этот — про микро-проверки, которые занимают минуты, но ловят большую часть провалов AI-генерации.

Цвет и контраст

  • Текст на цветных кнопках проверен по APCA, не только по 4.5:1.
  • Состояние disabled читается, но не «как активное» (Lc отличается минимум на 15 от активного).
  • Ошибки не передаются только цветом — есть иконка или текст.
  • Focus-индикатор имеет контраст ≥3:1 с любым фоном, на котором может появиться.
  • Плейсхолдеры в инпутах не используются как единственный лейбл.

Структура и семантика

  • Каждая «кнопка» в макете — это компонент Button, а не текст во фрейме.
  • Иконки-кнопки имеют скрытый текст или aria-label в спецификации.
  • Заголовки в макете идут по иерархии (H1 → H2 → H3), а не «по размеру шрифта».
  • У форм есть видимые лейблы, а не только плейсхолдеры.
  • Ссылки отличаются от обычного текста не только цветом.

Поведение

  • Tab-порядок в прототипе совпадает с визуальным.
  • Модалки имеют focus trap и возвращают фокус на триггер при закрытии.
  • Тосты и уведомления остаются на экране достаточно долго или имеют способ перечитать.
  • Анимации можно отключить (prefers-reduced-motion учтён в спецификации).
  • Время сессии и таймауты не «съедают» пользователя без предупреждения.

Анти-паттерны, которые AI генерирует чаще всего

«Призрачный disabled»

Модель уменьшает opacity у активной кнопки до 0.4 и называет это disabled. Контраст уезжает ниже допустимого, состояние почти не отличается от ховера на тёмной теме. Лечится только токеном состояния, заведённым руками.

Текст на градиенте

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

Иконка вместо кнопки

AI рисует «современный минималистичный интерфейс» — три точки, шестерёнка, стрелка. Что эти иконки делают, понятно только дизайнеру. Скринридер прочитает «button» и замолчит.

Псевдо-инпут

Поле ввода нарисовано как Rectangle с текстом внутри. Визуально — инпут. В коде после MCP-передачи — div. Никакой клавиатурной фокусировки, никакой автозаполнения, никакой ассистивной поддержки.

«Состояния потом»

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

Контраст «на скриншоте»

Дизайнер скидывает картинку макета в чат и спрашивает «как контраст?». Модель смотрит на сжатый JPEG и отвечает «нормально». Реальные значения цветов могут быть совсем другими.

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

Эти вопросы стоит задавать вслух — себе или коллеге — перед тем, как отправлять макет в разработку.

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

Если на любой из этих вопросов нет внятного ответа — макет ещё не готов, даже если выглядит красиво.

Практический итог

Доступность в эпоху AI-генерации — это не отдельная проверка в конце. Это набор привычек: писать промпт с ограничениями, держать токены состояний, проверять контраст по APCA, называть слои осмысленно, рисовать состояния, прогонять Tab по прототипу. Каждая по отдельности занимает минуты. Все вместе — экономят недели переделок и спасают аудиторию, которую никто из команды не увидит в обычной аналитике, потому что она просто не доходит до экрана. AI рисует быстро. Ответственность за то, как этим пользуются реальные люди, всё ещё на дизайнере.

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