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-макеты будут уезжать в прод с одинаковыми болячками месяц за месяцем.
Диагностика: как быстро понять, насколько плохо
Не каждому экрану нужен полный аудит. Но быстрый замер полезен — он показывает, можно ли вообще брать этот макет в работу или нужно возвращать на переделку.
Тест за пять минут
- Пройдите экран только клавишей Tab. Видно ли, где фокус? Логичен ли порядок?
- Включите серую шкалу в системе. Различимы ли статусы, ошибки, активные состояния?
- Уменьшите шрифт до 200% через зум браузера или симуляцию в Figma. Не ломается ли вёрстка, не обрезается ли текст?
- Прочитайте экран вслух как будто диктуете другу по телефону. Понятна ли структура без визуала?
- Спросите себя: что произойдёт, если поле ввода вернёт ошибку? Есть ли в макете этот стейт?
Если на любом из шагов спотыкаетесь — макет не готов, независимо от того, насколько он красивый.
Где смотреть 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 рисует быстро. Ответственность за то, как этим пользуются реальные люди, всё ещё на дизайнере.