Почему автолейаут ломается при импорте в Figma
Импорт прошёл, всё на своих местах. Потом вы тянете фрейм за край — и всё рассыпается.
Вы импортируете веб-страницу в Figma, панель слоёв заполняется, и что-то не сходится. Ряд карточек, который в браузере стоял вровень, теперь имеет одну карточку на четыре пикселя ниже. Центрированная навигация центрирована как-то приблизительно. Ничего не сломано настолько, чтобы ткнуть пальцем, но файл уже не совпадает со скриншотом, который вы оставили открытым рядом.
Почти всегда это Auto Layout, применённый там, где не следовало. Разобраться стоит, потому что решение — не «выключить Auto Layout», а понимать, когда две системы вёрстки действительно совпадают, а когда инструмент просто угадывает.
Два движка вёрстки, которые и не должны были совпасть
Браузер раскладывает страницу через CSS. Flexbox, grid, флоаты, строчный поток, схлопывание отступов, line-height, выталкивающий текст за пределы собственного бокса, субпиксельное округление, разное на разных платформах. Десятилетия правил, и большинство из них — краевые случаи, которые важны ровно один раз.
Figma раскладывает фрейм через Auto Layout. Система заметно меньше, и намеренно: одно направление, один отступ между элементами, четыре значения паддинга, выравнивание по двум осям, и на каждого потомка grow и stretch. Почти всё.
Auto Layout — не переизобретение flexbox. Он похож на flexbox примерно так, как велосипед похож на мотоцикл. Поэтому когда конвертер читает display: flex и ставит layoutMode: "HORIZONTAL", он делает утверждение: эти две системы поставят каждого потомка на одно и то же место. Иногда это правда. Часто — почти правда, и это хуже.
Где они тихо расходятся
Несколько конкретных случаев: все выглядят как flexbox, и ни один Auto Layout не воспроизводит.
- Отступы у флекс-элементов. В CSS потомок несёт собственный margin, вплоть до
margin-left: auto, чтобы отодвинуть группу вправо. У Auto Layout один отступ на весь фрейм и никакого margin у отдельного потомка. - space-around и space-evenly. У Auto Layout есть
SPACE_BETWEEN. Две другие раскладывают остаток пространства иначе, и настройки, которая их воспроизведёт, не существует. - align-items: baseline. Текст разного кегля, стоящий на общей базовой линии, — обычное дело в заголовках и строках с ценой. Auto Layout выравнивает по краям и центрам боксов, а не по базовым линиям.
- Дробный flex-grow.
flex: 1ложится наlayoutGrow: 1.flex: 2иflex: 0.5не ложатся никуда. - flex-wrap. Перенесённый ряд — другая геометрия, чем ряд в одну строку, и точка переноса зависит от ширины контейнера в момент захвата.
- Переизмерение текста. Вот на чём инструменты спотыкаются чаще всего. Текстовый слой, подогнанный под содержимое, измеряет сама Figma — своим шрифтом, в своём вычисленном кегле. Если это измерение разойдётся с браузером хотя бы на пиксель, все следующие за ним соседи в стопке сдвинутся.
Из-за последнего пункта проблема часто проявляется только после того, как вы установили недостающий шрифт, или только на чужой машине.
Почему конвертеры всё равно его ставят
Потому что файл, полный фреймов с Auto Layout, выглядит как продукт получше, чем файл, полный прямоугольников с абсолютными координатами. Хорошо смотрится в демонстрации и даёт строчку в списке возможностей. А в обычном случае — простой ряд, сетка карточек с равными промежутками — он действительно лучше: меняешь размер фрейма, и он ведёт себя как надо.
Загвоздка в том, что отличить обычный случай от «почти попал» без проверки нельзя, а проверять дороже, чем не проверять.
Что с этим делать
Если импорт уже сделан
Возьмите фрейм, который выглядит неправильно, и поставьте режим вёрстки в «нет» — это раздел layout в правой панели Figma. Потомки сохранят текущие позиции, так что если сдвиг уже случился, вы его этим замораживаете, а не отменяете. Поэтому полезное действие почти всегда — переимпортировать, а не чинить.
Перед этим проверьте одну вещь: установлены ли на вашей машине шрифты, которыми пользовалась страница? Подменённый шрифт заново измеряет каждый текстовый слой, и никакая возня с вёрсткой не спасёт файл, у которого текст не той ширины. Какие шрифты отсутствуют, Figma сообщает при открытии файла.
Если вы ещё выбираете инструмент
Спросите, что он делает, когда две системы расходятся. Ответов всего три, и годится один.
- Ставить Auto Layout везде, где виден flexbox. Быстро, эффектно в демонстрации, и вам отдают файл, который тихо съехал.
- Не ставить никогда. Всегда верно и совершенно бесполезно. Вы получаете кучу абсолютно позиционированных слоёв: точных и мучительных в правке.
- Ставить только там, где он воспроизводит оригинал. Верно и полезно, но требует, чтобы инструмент действительно предсказал поведение Figma и сравнил.
Как решает Snapture
Snapture выбирает третий вариант, и механизм умещается в абзац.
В момент захвата он уже знает, где находится каждый элемент, потому что прочитал отрендеренную страницу: у него есть настоящий, вычисленный браузером прямоугольник для каждого потомка. Прежде чем поставить вёрстку, он симулирует, что сделал бы с тем же фреймом движок Figma — паддинг, отступ, выравнивание, распределение grow — и получает предсказанный прямоугольник для каждого потомка. Затем сравнивает два набора. Если каждый потомок попадает в пределах половины пикселя от того места, куда его поставил браузер, вёрстка применяется. Если промахнулся хотя бы один, весь фрейм сохраняет точные абсолютные координаты.
С другой стороны есть вторая проверка. После того как плагин Figma применил вёрстку, он измеряет потомков заново — теперь против настоящего движка, а не против предсказания, — и если что-то сместилось дальше той же половины пикселя, возвращает фрейму захваченные координаты. Эта проверка нужна потому, что текстовый слой может быть переизмерен при импорте так, как не предвидит никакая симуляция.
Как это выглядит на практике
Прогон конвертера по реальным страницам даёт представление о том, насколько он разборчив. Это цифры из той же серии измерений, что опубликована на странице измерений.
| Страница | Узлов всего | Фреймов с Auto Layout |
|---|---|---|
| linear.app | 2082 | 261 |
| stripe.com | 1592 | 99 |
| tailwindcss.com | 1540 | 89 |
| github.com | 785 | 42 |
| developer.mozilla.org | 253 | 5 |
Интересна строка MDN. Пять фреймов с Auto Layout на 253 узла выглядят как провал инструмента. Это инструмент за работой: вёрстка статей MDN — по большей части документный поток и флоаты, которые Auto Layout вообще не моделирует, поэтому фильтр отклонил почти всё и сохранил точные позиции. Для той страницы это правильный размен.
Linear, наоборот, собран почти целиком из флекс-рядов с равномерными промежутками. 261 его фрейм действительно проходит сравнение, и эти фреймы ведут себя правильно, когда вы меняете их размер в Figma.
Коротко
Auto Layout после импорта заслуживает доверия только если что-то его проверило. Flexbox и Auto Layout пересекаются достаточно, чтобы обмануть конвертер, и различаются достаточно, чтобы сдвинуть ваш файл, а разница обычно проявляется как несколько пикселей, а не как очевидная поломка — то есть как ошибка, которую дороже всего искать.
Если инструмент не может сказать, что он делает при расхождении, считайте, что он не проверяет.
Попробуйте на своих страницах Пять бесплатных захватов со всеми функциями. Без карты и без аккаунта.English · 한국어 · 日本語 · 简体中文 · 繁體中文 · Español · Português · Français · Deutsch · Русский · Italiano · Bahasa Indonesia