Слогер Создать блог
Разработка

Почему Claude не может сверстать по скриншоту из Figma: разбор и альтернатива

Скриншот превращает структуру макета в пиксели: иерархия, токены, компоненты и строки теряются. Разбираем, как передавать дизайн агенту правильно.

Когда дизайнеры и разработчики начинают кидать скриншоты из Figma в Claude, кажется — вот оно, решение. Быстрая вёрстка по кнопке. Но на практике макет превращается в мусор на входе: нейросеть не видит структуру, а угадывает её. И угадывает по-разному каждый раз.

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

Скриншот убивает иерархию

Файл Figma — это дерево. Фреймы содержат auto-layout группы, те — инстансы компонентов, а внутри лежат тексты и заливки. Дерево кодирует намерение: эти три элемента — соседи с отступом 16px, а карточка — контейнер с паддингами.

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

По PNG невозможно сказать, свёрстан ли горизонтальный ряд через flex, CSS Grid, кастомный HStack или три абсолютно спозиционированных div. Визуально они идентичны. LLM выбирает один вариант. И этот выбор меняется от запуска к запуску.

Семантика не переживает растеризацию

LLM видит, что прямоугольник со скруглёнными углами содержит текст и иконку. Чего она не видит:

  • Это Button или кастомная карточка?
  • Если кнопка, то какой вариант — primary, secondary, ghost?
  • Иконка декоративная или смысловая?
  • Есть ли у элемента интерактивные состояния в дизайн-системе?

В Figma семантика живёт в слоях: имена компонентов, свойства вариантов, типы узлов. Компонент Button/Primary/Large типизирован явно. На скриншоте это просто прямоугольник с тенью и подписью. Модель правильно угадывает «это кнопка» в большинстве случаев — а затем угадывает «это primary» по цвету, который может не совпадать с реальными именами вашей дизайн-системы.

Мелкие расхождения накапливаются. Ghost-кнопка свёрстана как контурная. Тултип — как модальный триггер. Неактивное состояние — как активное. Каждая ошибка — на расстоянии одного шага вывода от источника истины.

Система отступов не превращается в числа

Смотрите на скриншот карточки с паддингом. Какой там паддинг? Чтобы узнать, нужно измерять пиксели, знать масштаб канвы, знать разрешение экспорта и считать. LLM считает плохо — оценивает, округляет и не имеет способа узнать, используете ли вы сетку 8px, 4px или что-то своё.

В результате модель генерирует padding: 12px, когда в дизайне 16. Генерирует gap: 8px, когда надо 12. По отдельности числа выглядят правдоподобно, но они неправильные. А если у вас в дизайн-системе токены вроде spacing.md или Spacing/400 — LLM о них вообще не знает и хардкодит литералы, которые разойдутся с системой при любом изменении.

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

Токены и связи исчезают

Дизайнер поставил фон #7F5CFE. В Figma этот hex привязан к переменной color/brand/primary. Связь означает, что цвет участвует в темизации, что тёмная тема его заменяет, что при смене брендового цвета вы обновляете одну переменную — и все инстансы обновятся.

На скриншоте — просто фиолетовый. LLM генерирует background-color: #7F5CFE. Связь с токеном потеряна. В кодовой базе появляется захардкоженный hex, который никогда не будет следить за дизайн-системой. Умножьте это на каждый компонент экрана.

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

Компоненты и строки становятся невидимыми

Хорошо собранный экран переиспользует компоненты. Четыре карточки товара — это четыре инстанса одного ProductCard. Аватар в навигации и аватар в комментариях — оба Avatar/Medium. Это важно для кода: нужен один React-компонент, а не четыре рукописных вариации, которые разойдутся в будущем.

На скриншоте LLM видит четыре визуально похожих прямоугольника. Она может сгенерировать один переиспользуемый компонент — а может и четыре почти одинаковых блока JSX, потому что не заметила, что это одно и то же. В изображении нет сигнала, который подсказал бы правильный ответ.

Структурированный контекст несёт componentId на каждом узле-инстансе. Агент знает: эти четыре узла — один ProductCard. Сгенерируй его один раз, отрендери четыре раза с разными пропсами. Именно такой результат вам нужен. Именно такой результат из пикселей не получить.

Со строками та же история. Кнопка «Continue» на трёх экранах — это одна и та же строка или дизайнер написал её независимо? В хорошо структурированном файле они ссылаются на один строковый ключ. В трёх скриншотах — три раза LLM генерирует захардкоженную строку. Если вы делаете i18n-приложение, вам придётся искать и заменять три строки вместо одной. Мелочь, которая разрастается по реальной кодовой базе.

Сравнение: скриншот и структурированный контекст

ПараметрСкриншотIR (структурированный контекст)
ИерархияСплющена в пиксели, структура угадываетсяДерево узлов: фреймы, auto-layout, дети
ТокеныПросто числа и цветаИменованные ссылки: color/brand/primary, spacing/400
КомпонентыВизуально похожие фигурыcomponentId, имя варианта, пропсы
СтрокиТекст как картинкаstringRef.key для i18n
ВоспроизводимостьРазный вывод на каждом запускеДетерминированный вход, стабильный вывод

Возьмите карточку товара: картинка, заголовок, подзаголовок, цена, кнопка «В корзину». Скриншот даёт агенту прямоугольник с картинкой, двумя строками текста, числом и кнопкой. Цвета и отступы — оценка. IR даёт спецификацию: фрейм ProductCard с auto-layout по вертикали, gap 16px, паддинги по 16px, дочерние узлы с типами, стилями и ссылками на токены.

Что делать: передавайте структуру, а не картинку

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

  1. Соберите IR из Figma через API или специальную утилиту вроде figmascope — получите ZIP с CONTEXT.md, tokens.json, IR по экранам, списком компонентов и манифестом строк.
  2. Положите этот контекст в проект рядом с кодом. Агент будет читать его как спецификацию.
  3. Скриншоты оставьте только для визуальной проверки — в бандле есть PNG в 2x именно для этого.
  4. Для Claude Code, Cursor и Aider уже есть готовые пайплайны такого хендоффа — не надо изобретать своё.

Главный сдвиг — перестать ожидать от модели магии и начать давать ей нормальные данные. Скриншот — это подсказка. IR — это спецификация.

Структурированный контекст решает проблему воспроизводимости. Два разработчика с одним и тем же файлом Figma, но разными скриншотами и запросами получат разную архитектуру кода. С одинаковым IR — одинаковые решения по компонентам, токенам и вложенности. Не идеально детерминированно, но вариативность падает радикально, когда структура задана, а не выведена из пикселей.

По материалам: dev. Текст переработан редакцией Слогера.

← На главную

Рекламное место — Конец поста
Реклама · Слогер

Комментарии (0)

Войдите, чтобы комментировать.

Пока нет комментариев. Будьте первым.