Семантика для дизайнеров: почему это не только задача разработчика
Main chat
A chat for vibe coders: news, guides, live cases, marketplace, and finding executors.
Дизайнер сдал макет, разработчик закодил, QA проверил пиксели. Через месяц приходит письмо от пользователя со скринридером: «я не могу пройти ваш онбординг». Открываете инспектор — половина кнопок это <div>, заголовки идут h1 → h4 → h2, форма без label, иконка-кнопка без названия.
И первая мысль — «это к разработчику». А вот и нет.
Семантика начинается в Figma, а не в редакторе кода. Если в макете кнопка нарисована как прямоугольник без статуса «кнопка», если заголовки расставлены по размеру шрифта, а не по смысловой иерархии, если поле ввода живёт отдельно от подписи — разработчик унаследует эту неоднозначность и закодит как умеет. Чаще всего — буквально: div поверх div.
Почему это вообще проблема дизайнера
Семантика — это не «доступность для слепых», как иногда сокращают на планёрках. Это смысловой каркас интерфейса, от которого зависят сразу несколько вещей:
- Скринридеры и голосовое управление — без ролей и подписей продукт просто не работает для части людей.
- Поисковая выдача и шеринг — корректные
h1,meta,altнапрямую влияют на то, как страница выглядит в Google и в превью мессенджера. - AI-агенты и автоматизация — LLM-браузеры и автозаполнение опираются на семантику DOM. Кнопка-
divдля агента не существует. - Тестируемость — автотесты, которые ищут по роли и имени, стабильнее, чем тесты по CSS-селекторам. Это напрямую экономит время команды.
- Передача макета в код — Figma Dev Mode, MCP, плагины кодогенерации тянут структуру из слоёв. Каша в слоях = каша в коде.
То есть семантика — это не благотворительность. Это качество продукта, которое видно в метриках: конверсия мобильных пользователей, индексация, время онбординга, стоимость поддержки.
Где дизайнер теряет семантику первым
Иерархия заголовков по размеру шрифта
Классика: в макете три «заголовка» — 32, 24 и 18 px. Разработчик смотрит на размер и расставляет h1, h2, h3. А по смыслу страницы там должно быть, например, один h1 и два h2 на одном уровне, просто визуально разного веса.
Размер шрифта — это стиль. Уровень заголовка — это структура. Это разные вещи, и их нужно разводить ещё в макете.
Как делать на практике:
- В дизайн-системе называйте стили по смыслу:
Heading/Page,Heading/Section,Heading/Subsection, а неText/32,Text/24. - В макете подписывайте, где
h1, гдеh2. Достаточно тега во фрейме или комментария в Dev Mode. - На странице должен быть один
h1. Если их два — это вопрос к дизайну, а не к разработчику.
Кнопка, ссылка и «кликабельная штука»
Визуально это может быть один и тот же прямоугольник. Семантически — три разные вещи:
- Кнопка — действие в текущем контексте (отправить форму, открыть модалку, добавить в корзину).
- Ссылка — переход на другой URL, в том числе внутри SPA.
- Переключатель/чекбокс/радио — изменение состояния.
Если дизайнер не различает их в макете, разработчик угадывает. И угадывает плохо: «кнопка назад» становится <div onClick>, теряет фокус с клавиатуры, не работает в средней кнопке мыши, не озвучивается скринридером.
Анти-паттерны, которые видно прямо в Figma:
- «Кнопка-стрелка» без подписи и без названия слоя. В коде она станет иконкой без
aria-label. - Целая карточка-ссылка, в которой ещё лежит кнопка. На вёрстке это превратится во вложенные интерактивы, что технически невалидно.
- «Tab» нарисованный как набор кнопок без указания, какая активна. Состояние
aria-selectedберётся из воздуха.
Формы без связки label ↔ input
В макете подпись «Email» лежит над полем как отдельный текстовый слой. Формально всё ок. Но если эта связь не зафиксирована, в коде получится поле без <label for>, и тап по подписи не сфокусирует input — особенно больно на мобильных.
Чеклист для любого поля в макете:
- У поля есть видимая подпись (не только плейсхолдер).
- Подпись и поле сгруппированы в один компонент/фрейм.
- Состояния ошибки, подсказки и «обязательное» нарисованы и подписаны.
- У поля есть имя в слоях —
Input/Email, а неRectangle 482. - Иконка внутри поля (глаз, очистка) имеет имя и описана как кнопка, если кликается.
Короткий итог сегмента: семантика — это та часть качества, которую дизайнер закладывает в макет, а не та, которую «должен был добавить разработчик». Дальше разберём, как встроить это в дизайн-систему, ревью и работу с AI-инструментами.
Как встроить семантику в дизайн-систему
Семантика держится не на героизме одного дизайнера, а на том, что компоненты библиотеки уже несут в себе смысл. Если в системе кнопка — это Button, а не Rectangle + Text, шанс, что она доедет до кода правильной, сильно выше.
Именование компонентов по роли, а не по виду
Плохие имена: Blue Box, CTA Big, Card 3. Хорошие имена: Button/Primary, Link/Inline, Card/Article, Field/Text, Tabs/Item.
Имя в библиотеке — это первое, что увидит и человек, и LLM, и плагин кодогенерации. Если компонент называется по смыслу, дальше в коде он почти всегда становится правильным тегом.
Свойства, которые описывают поведение
В variants стоит закладывать не только цвет и размер, но и роль:
- У
Button— свойствоtype:button | submit | link. Да, прямо так, как в HTML. - У
Input— свойстваlabel,required,error,helper. Если их нет в компоненте, их не нарисуют. - У
Heading— свойствоlevel:h1 | h2 | h3 | h4. Размер отдельно, уровень отдельно. - У
Icon— свойствоdecorativeилиlabel. Иконка либо декор, либо несёт смысл и требует подписи.
Это та точка, где дизайн-система начинает разговаривать с разработкой на одном языке.
Структура слоёв = структура DOM
Внутри компонента порядок и группировка слоёв уже подсказывают вёрстку. Если внутри карточки сначала идёт картинка, потом заголовок, потом описание, потом кнопка — так оно и будет в коде. Если всё свалено в один фрейм с абсолютным позиционированием, разработчик соберёт это как сможет.
Простое правило: открой слои компонента и прочитай их сверху вниз вслух. Получился осмысленный кусок страницы — ок. Получилось «прямоугольник, прямоугольник, текст, прямоугольник» — переделывай.
Рабочий процесс: где семантика встраивается в день дизайнера
На этапе вайрфрейма
Семантика закладывается до визуала. На вайрфрейме уже видно: тут заголовок страницы, тут раздел, тут список, тут форма из трёх полей. Если на этом шаге не разложить структуру, дальше её будет дорисовывать кто угодно — кроме вас.
Полезная привычка: рядом с вайрфреймом писать словами, что это за экран. «Страница товара. h1 — название. h2 — характеристики, отзывы, похожие. Основное действие — купить.» Три строки текста экономят день споров.
На этапе макета
- Компоненты только из библиотеки. Любой
Rectangleс onClick в голове — звоночек. - Все интерактивы названы по типу действия:
Button/Add to cart, а неButton/Yellow. - Состояния (hover, focus, disabled, error, loading) нарисованы для всего, что кликается или вводится.
- Порядок фокуса понятен из расположения. Если по Tab пользователь должен прыгать сначала направо, потом вниз, это надо явно отметить.
На передаче в разработку
В Dev Mode или в комментариях фиксируем то, что не видно глазом:
- Уровень заголовков.
- Какие элементы — кнопки, какие — ссылки.
- Тексты для
aria-labelу иконочных кнопок. - Порядок чтения и фокуса, если он отличается от визуального.
- Что является «живым регионом» — тосты, ошибки формы, индикаторы загрузки.
Это занимает 10–15 минут на экран и снимает половину вопросов на код-ревью.
Когда в процессе появляется AI
Кодогенерация из Figma, MCP-серверы, ассистенты в IDE — все они читают то, что вы положили в макет. Если структура слоёв осмысленная и компоненты названы по роли, ИИ выдаёт довольно приличный код. Если в макете каша — ИИ уверенно сгенерирует красивую кашу, и это будет сложнее чинить, чем писать с нуля.
Главный риск тут не «ИИ ошибётся», а «никто не заметит, что он ошибся». Поэтому ИИ-сборку всё равно нужно проверять по той же семантической линейке: правильные теги, доступные имена, рабочая клавиатура.
Быстрая диагностика готового макета
Прогон по этому списку занимает минут пять и ловит большую часть проблем до того, как они уедут в код.
- На странице один
h1, и он отвечает на вопрос «о чём этот экран». - Уровни заголовков идут без перепрыгивания: после
h2не появляетсяh4. - Все кликабельные элементы — компоненты
ButtonилиLink, не голые фреймы. - Иконочные кнопки имеют текстовую подпись для скринридера.
- У каждого поля формы есть видимый label и нарисованы состояния ошибки и фокуса.
- Слои названы по смыслу, в библиотеке нет
Frame 128иGroup 14. - Состояния
selected,expanded,currentявно отмечены — и визуально, и в подписях. - Модалки, тосты и подсказки помечены как отдельные роли, а не «просто плашка сверху».
Вопросы, которые стоит задавать на дизайн-ревью
- Если убрать цвет и иконки, останется ли понятна структура страницы?
- Можно ли пройти этот экран только с клавиатуры? В каком порядке?
- Что услышит человек со скринридером на главной кнопке? А на иконке-крестике?
- Какой
h1у этой страницы и почему именно он? - Что отличает «кнопку» от «ссылки» в этом макете, кроме цвета?
- Какие элементы динамически меняются и должны быть объявлены скринридеру?
Если на эти вопросы автор макета отвечает уверенно — семантика на месте. Если плывёт — лучше доразобраться сейчас, чем читать баги через спринт.
Короткий итог: семантика встраивается в три точки — библиотеку компонентов, привычки на макете и ревью перед передачей. Ни одна из этих точек не требует кода, но именно они определяют, каким продукт окажется в браузере, в скринридере и в руках у ИИ-агента.
Когда в работу заходит AI-агент или MCP
Связка «Figma → MCP-сервер → IDE-ассистент» сейчас выглядит как магия: дизайнер отдаёт фрейм, через пару минут в репозитории появляется компонент. Но магия работает ровно до тех пор, пока в макете есть смысл, который агент может прочитать. Имена слоёв, типы компонентов, варианты, авто-лейаут — для агента это не косметика, а единственный источник правды о структуре.
Что агент реально читает
Грубо говоря, агент видит дерево слоёв и свойства компонентов. Из этого он пытается угадать:
- что является контейнером, а что — контентом;
- где кнопка, где ссылка, где просто текст;
- какие элементы повторяются и должны стать списком;
- что меняется между вариантами — состояние, размер или вообще другой компонент.
Если у вас Frame 412 / Frame 87 / Rectangle 3, агент честно сгенерирует <div><div><div>. Если у вас ProductCard / Header / Title, шанс получить нормальную разметку радикально выше.
Рабочий процесс, который не разваливается
- Перед передачей в агент прогоняем макет по тому же чеклисту, что и для верстальщика-человека.
- В описании задачи для агента прямо пишем семантику: «это карточка товара, заголовок — h3, кнопка — основной CTA, цена — не заголовок».
- Сгенерированный код смотрим в первую очередь на теги и роли, а не на пиксели. Пиксели починить легко, перепаханную структуру — дорого.
- Доступные имена и aria-атрибуты для иконочных кнопок прописываем руками или явным промптом. Агент их почти никогда не угадывает.
Анти-паттерны при работе с AI
- «Сгенерируем, а потом разберёмся». Не разберётесь: семантические ошибки расползаются по компонентам и копируются дальше.
- Доверять агенту структуру заголовков. Он легко поставит
h1на каждой карточке. - Принимать PR от агента без открытия его в браузере с клавиатуры и скринридера. Визуально всё может быть идеально, а Tab улетает в никуда.
Как проверять качество, если нет аудитора рядом
Не нужно ждать отдельного цикла доступности, чтобы понять, что макет или сборка живые. Есть несколько дешёвых проверок, которые умещаются в обычный рабочий день.
Пятиминутный проход по готовому экрану
- Открыть страницу и пройти её только клавишей Tab. Зафиксировать порядок, отметить места, где фокус исчезает или прыгает.
- Включить системный скринридер на десять минут. Послушать главную кнопку, иконку-крестик, поле формы с ошибкой.
- Открыть инспектор и посмотреть дерево заголовков. Один
h1, дальше ровная иерархия — или каша. - Уменьшить окно до мобильной ширины и убедиться, что порядок чтения не сломался.
- Отключить CSS (или посмотреть reader mode). Если содержимое читается логично — структура жива.
Что считать «достаточно хорошо»
Идеальная семантика — миф, особенно в больших продуктах. Полезнее держать в голове три уровня:
- Базовый: правильные теги для интерактивов, заголовки, формы с label, фокус виден.
- Рабочий: к базовому добавляются состояния, live-регионы для тостов и ошибок, осмысленные
aria-labelу иконок. - Зрелый: к рабочему — продуманные landmark-области, корректные роли у кастомных виджетов, тесты доступности в CI.
Большинству команд достаточно уверенно жить на «рабочем» уровне и подтягивать «зрелый» там, где это критично — формы оплаты, личный кабинет, регистрация.
Как объяснить решение команде
Семантика часто звучит как «дизайнер придирается». Поэтому аргументация должна быть не про правила, а про последствия.
Язык, который работает
- С разработчиком: «если это будет
div, нам придётся вручную навешивать роль, фокус и обработчики клавиатуры — кнопка делает это сама». - С продактом: «сейчас на странице три h1, поисковик не понимает, о чём она. На ревью видно, что такие страницы хуже ранжируются».
- С менеджером: «через полгода мы захотим переиспользовать этот блок. Если он называется
Frame 128, никто его не найдёт». - С другим дизайнером: «давай не красить ссылку как кнопку — пользователи на клавиатуре ожидают от неё другое поведение».
Вопросы для общего ревью
- Какую роль играет каждый интерактивный элемент — кнопка, ссылка, переключатель?
- Что произойдёт, если пользователь дойдёт сюда с клавиатуры?
- Какие сообщения должны быть объявлены автоматически, а какие — только по запросу?
- Что увидит и услышит человек, если визуальный слой не загрузится?
- Что из этого экрана будет переиспользовано, и переживёт ли оно переименование?
Если на ревью эти вопросы становятся привычными, семантика перестаёт быть личной войной одного дизайнера и превращается в общий стандарт.
Короткий итог сегмента: семантика на продвинутом уровне — это не больше тегов, а больше дисциплины. Тот же чеклист работает и для верстальщика, и для AI-агента; те же вопросы задаются и на дизайн-ревью, и на код-ревью. Чем меньше разницы между этими разговорами, тем спокойнее живёт продукт.
Финальный чеклист: что должно быть в голове на каждом макете
Семантика хорошо работает, когда становится частью обычной проверки макета, а не отдельным ритуалом. Ниже — минимальный набор пунктов, который имеет смысл прогонять перед тем, как кидать макет в работу или принимать PR.
Чеклист дизайнера перед передачей
- У каждого экрана есть один главный заголовок и понятная иерархия ниже.
- Все интерактивные элементы названы по роли: кнопка, ссылка, переключатель, поле. Не «прямоугольник со стрелкой».
- У иконочных кнопок прописано доступное имя — текстом в спецификации или в комментарии к компоненту.
- У форм есть видимые подписи, состояния ошибки и подсказки, а не только плейсхолдеры.
- Порядок чтения совпадает с порядком в макете: сверху вниз, слева направо, без сюрпризов.
- Состояния hover, focus, active, disabled нарисованы, а не оставлены «как у браузера».
- Тосты, баннеры и инлайн-ошибки помечены: что объявляется автоматически, а что — нет.
- Названия слоёв и компонентов читаются человеком, а не Auto Layout-генератором.
Чеклист для код-ревью со стороны дизайнера
- Главный CTA — это
buttonилиa, а неdivс обработчиком. - Заголовки не выбраны по размеру шрифта, а отражают структуру.
- Список выглядит как список и в разметке.
- Модалка получает фокус при открытии и возвращает его обратно при закрытии.
- Скрытое визуально не значит скрытое для скринридера, и наоборот.
- Цветовой контраст не сломан тёмной темой и брендовыми акцентами.
Анти-паттерны, которые регулярно всплывают
Эти ошибки повторяются из проекта в проект независимо от стека и размера команды. Полезно держать их в голове как отдельный список.
В макете
- Заголовок ради размера. «Сделаем покрупнее, чтобы заметили» превращается в третий
h1на экране. - Кнопка-ссылка-кнопка. Один и тот же элемент в разных местах выглядит то ссылкой, то кнопкой. Пользователь на клавиатуре перестаёт понимать, что произойдёт.
- Плейсхолдер вместо лейбла. Поле выглядит чистым, пока в него не начали печатать — и тогда подпись исчезает.
- Иконка без имени. Крестик, троеточие, шестерёнка без подписи. Глазами понятно, ушами — нет.
- Сетка вместо смысла. Карточки выстроены красиво, но порядок чтения идёт зигзагом.
В коде и в работе с AI
- «Починим потом». Семантику почти никогда не чинят потом: её закапывают новыми компонентами.
divсonClickкак стандарт. Один раз разрешили — и теперь это шаблон в кодовой базе.- Слепой прогон агентом. PR от AI без открытия в браузере, без клавиатуры, без скринридера.
- Aria поверх боли. Когда вместо нормального тега навешивают пять атрибутов, чтобы «озвучить как надо».
Вопросы для дизайн- и продуктового ревью
Эти вопросы удобно задавать вслух — себе, автору макета, разработчику. Они быстро вытаскивают слабые места.
- Какой здесь главный элемент экрана и почему именно он?
- Что произойдёт, если пройти этот экран только клавиатурой?
- Какие сообщения пользователь должен услышать, даже если не смотрит на экран?
- Где здесь кнопки, а где ссылки, и совпадает ли это с поведением?
- Что из этого экрана будет жить в библиотеке через год, и как оно называется сейчас?
- Если убрать визуальный слой, останется ли понятным, о чём страница?
Если на этих вопросах команда спотыкается каждый раз — это сигнал, что семантика не встроена в процесс, а живёт в голове одного человека.
Практический итог
Семантика для дизайнера — это привычка задавать про каждый элемент два вопроса: чем он является и как он будет прочитан без картинки. Всё остальное — теги, роли, атрибуты, имена слоёв, промпты к агенту — производное от этих двух вопросов.
Когда такая привычка появляется, исчезает разрыв между макетом и кодом: разработчику не нужно догадываться, что имелось в виду, агенту — придумывать структуру, аудитору — переписывать половину компонентов. Появляется одна общая модель экрана, на которую опираются все.
И именно в этот момент доступность, SEO, переиспользуемость компонентов и понятная аналитика перестают быть отдельными задачами. Они становятся побочным эффектом того, что в макете и в разметке наконец-то называется одно и то же — одинаково.