Коротко:
- Хаос в отступах почти всегда начинается с одного и того же: каждый компонент проектируется отдельно, без общей базовой единицы.
- Рабочая основа - кратность 4px или 8px. Все значения в шкале строятся из неё.
- Внутренние отступы компонента (padding) и расстояния между блоками (margin, gap) подчиняются разным правилам, но берутся из одной шкалы.
- Шкала фиксируется в токенах - именованных переменных, которые подключаются к компонентам в Figma и передаются в код.
- Самая частая ошибка - задать шкалу, но не договориться с командой, когда какое значение использовать.
Почему отступы разваливаются без системы
Открываешь файл через полгода - и видишь 24px здесь, 20px там, 18px в третьем месте. Все похожи, но ни одно не совпадает. Разработчик спрашивает: «Это разные значения намеренно?» Дизайнер отвечает: «Нет, просто так получилось».
Так и работает большинство проектов без явной системы отступов: каждый экран проектируется на глаз, значения подбираются интуитивно, и со временем накапливается десяток почти одинаковых чисел, которые невозможно поддерживать.
Spacing-система в интерфейсе решает эту проблему не за счёт жёстких ограничений, а за счёт заранее согласованной шкалы. Вместо «сколько кажется правильным» - «какое значение из шкалы здесь подходит».
Базовая единица: 4px или 8px
Большинство современных интерфейсов строится на кратности 8px. Это не случайность: экраны с плотностью 1x, 2x и 3x одинаково хорошо отображают числа, кратные 8, без субпиксельного размытия. Плюс 8pt grid система хорошо ложится на стандартные размеры компонентов - кнопки, поля ввода, иконки.
Кратность 4px используют там, где нужна более тонкая градация: маленькие компоненты, плотные интерфейсы, мобильные приложения с компактным контентом. Четвёрка даёт вдвое больше шагов при той же максимальной величине.
Выбор между ними - не принципиальный. Важнее другое: выбрать одну единицу и не отступать от неё. Смешивать 8px-логику с произвольными значениями вроде 10px или 15px - это и есть источник хаоса.
Пример: Если базовая единица - 4px, то допустимые значения: 4, 8, 12, 16, 20, 24, 32, 40, 48, 64. Значение 18px в эту шкалу не вписывается - это сигнал, что где-то произошло отклонение.
Как построить шкалу отступов
Шкала - это не просто список чисел. Это набор именованных шагов, каждый из которых решает конкретную задачу в интерфейсе.
Типичная шкала на базе 4px выглядит так:
| Токен | Значение | Где применяется |
|---|---|---|
| spacing-1 | 4px | Иконка рядом с текстом, метка над полем |
| spacing-2 | 8px | Внутренний отступ маленького компонента, gap между иконками |
| spacing-3 | 12px | Padding кнопки по вертикали, отступ внутри тега |
| spacing-4 | 16px | Стандартный padding карточки, отступ между строками списка |
| spacing-5 | 24px | Расстояние между группами элементов внутри блока |
| spacing-6 | 32px | Отступ между секциями внутри экрана |
| spacing-7 | 48px | Крупные блоки, разделители между секциями страницы |
| spacing-8 | 64px | Отступы между крупными секциями лендинга или дашборда |
Названия токенов могут быть числовыми (spacing-1, spacing-2) или семантическими (spacing-xs, spacing-sm, spacing-md). Семантические удобнее для коммуникации с разработчиком: «используй spacing-md» понятнее, чем «используй spacing-4». Числовые проще масштабировать, если шкала расширяется.
Padding и margin: разные задачи, одна шкала
Внутренние и внешние отступы решают принципиально разные задачи, хотя берутся из одной шкалы.
Padding - это пространство внутри компонента между его границей и содержимым. Он определяет «воздух» вокруг текста кнопки, иконки или ячейки таблицы. Padding влияет на размер компонента и его визуальный вес.
Gap и margin - это расстояние между компонентами или блоками. Они определяют, насколько плотно или свободно элементы стоят рядом.
Ошибка, которую часто допускают: используют одинаковые значения для padding внутри компонента и для расстояния между компонентами, не думая о контексте. В результате кнопка выглядит слишком воздушной, а соседние блоки слипаются.
Правило: Padding внутри компонента обычно меньше, чем расстояние между группами компонентов. Кнопка с padding 12px по вертикали и 16px по горизонталу - норма. Расстояние между кнопкой и следующим блоком - уже 24px или 32px.
Отступы внутри компонентов
Когда проектируешь компонент, отступы внутри него нужно задавать через padding, а не через фиксированную высоту. Это позволяет компоненту адаптироваться к содержимому.
Для кнопок стандартная логика такая: padding по вертикали определяет высоту, padding по горизонталю - ширину. Если кнопка маленькая (size: sm), берём spacing-2 и spacing-3. Если стандартная (size: md) - spacing-3 и spacing-4. Если крупная (size: lg) - spacing-4 и spacing-5.
Для карточек внутренний отступ обычно одинаковый со всех сторон - чаще всего spacing-4 (16px) или spacing-5 (24px). Если карточка плотная (таблица, список) - spacing-3. Если карточка «дышащая» (онбординг, промо) - spacing-6 или spacing-7.
Расстояние между элементами внутри компонента - например, между иконкой и текстом в кнопке - берётся из нижней части шкалы: spacing-1 или spacing-2. Это маленькие значения, которые создают связь между элементами, не разрывая их.
Отступы между блоками и секциями
Здесь работает другая логика: чем крупнее блок, тем больше пространство вокруг него. Это создаёт визуальную иерархию без лишних разделителей.
Внутри одной секции элементы стоят близко - spacing-4 или spacing-5. Между секциями на одном экране - spacing-6 или spacing-7. Между крупными смысловыми блоками (например, между хедером и основным контентом, или между секциями лендинга) - spacing-7 или spacing-8.
Такая градация помогает глазу считывать структуру страницы без явных рамок и разделителей. Пространство само по себе становится навигационным сигналом.
Представим дашборд: Внутри карточки метрики - padding 16px. Между карточками в ряду - gap 16px. Между рядом карточек и следующей секцией с графиком - 32px. Между графиком и таблицей ниже - 32px. Между основным контентом и футером - 48px. Каждый шаг берётся из шкалы, ничего не подбирается на глаз.
Как зафиксировать всё в токенах Figma
Шкала, которая живёт только в голове или в заметках, не работает. Её нужно зафиксировать так, чтобы любой участник команды мог взять правильное значение без лишних вопросов.
В Figma для этого используют Variables (переменные) - они появились в 2023 году и заменили старый подход через Styles. Spacing-токены создаются как Number Variables в коллекции, например «Spacing».
Процесс выглядит так:
- Открываешь панель Variables (Edit - Local Variables).
- Создаёшь коллекцию «Spacing».
- Добавляешь переменные типа Number: spacing-1 = 4, spacing-2 = 8 и так далее.
- Привязываешь переменные к padding и gap в Auto Layout компонентов.
После этого, если нужно изменить базовую единицу или скорректировать шаг шкалы, достаточно поменять значение одной переменной - все компоненты, которые её используют, обновятся автоматически.
Для передачи в разработку токены экспортируются через плагины: Tokens Studio (бывший Figma Tokens), Style Dictionary или встроенный Dev Mode в Figma. Разработчик получает именованные значения, а не набор пикселей из инспектора.
Важно: Spacing-токены должны называться одинаково в Figma и в коде. Если в Figma переменная называется spacing-4, а в CSS она превращается в --space-md без явного маппинга - это источник расхождений. Договоритесь о нейминге до начала работы.
Когда шкала не работает: честные ограничения
Фиксированная шкала хорошо работает для типовых компонентов и стандартных экранов. Но есть ситуации, где она создаёт трение.
Вакансии для дизайнеров
Адаптив. На мобильном экране spacing-7 (48px) между секциями может съедать слишком много места. Нужна либо отдельная мобильная шкала, либо токены с несколькими режимами (Modes в Figma Variables). Например, spacing-section = 48px на десктопе и 32px на мобайле.
Маркетинговые страницы. Лендинги и промо-экраны часто требуют нестандартных решений: огромные отступы для «воздуха», нестандартные пропорции. Здесь шкала работает как ориентир, но не как жёсткое правило.
Унаследованный код. Если проект уже существует и в нём сотни компонентов с произвольными значениями, внедрение шкалы - это постепенный процесс, а не одномоментная замена. Начинают с новых компонентов, постепенно рефакторя старые.
Типичные ошибки при внедрении
Слишком много шагов в шкале. Если шкала содержит 15 значений от 2px до 128px, команда всё равно будет выбирать «на глаз» - просто из большего набора. Рабочая шкала - 7-9 значений с понятными смысловыми ролями.
Шкала есть, договорённостей нет. Создать токены - это половина работы. Вторая половина - договориться, когда использовать spacing-4, а когда spacing-5. Без этого разные дизайнеры будут выбирать разные значения для одинаковых ситуаций.
Padding задаётся через фиксированную высоту. Если кнопка имеет height: 40px вместо padding-top: 10px + padding-bottom: 10px, она не масштабируется при изменении текста или шрифта. Всегда используй padding, а не фиксированный размер.
Разные шкалы для разных платформ без явного маппинга. Если мобильная и десктопная версии используют разные наборы значений, это нормально - но только если маппинг зафиксирован в токенах. Иначе разработчик получает два несвязанных набора чисел.
Игнорирование gap в Auto Layout. Многие дизайнеры задают padding правильно, но расстояние между элементами внутри Auto Layout оставляют произвольным. Gap - такой же отступ, он тоже должен браться из шкалы.
Чеклист: внедрение шкалы отступов
- Выбрана базовая единица: 4px или 8px
- Шкала содержит 7-9 значений с именованными токенами
- Каждый токен имеет описание: где и когда использовать
- Токены созданы как Variables в Figma (тип Number)
- Компоненты используют токены через Auto Layout (padding и gap)
- Нейминг токенов согласован с разработчиком
- Для адаптива настроены Modes или отдельная мобильная шкала
- Команда договорилась о правилах применения (не только о значениях)
- Новые компоненты проверяются на соответствие шкале перед хендофом
Spacing и адаптив: как шкала меняется при переходе между устройствами
Одна из самых частых проблем при внедрении системы отступов: шкала отлично работает на десктопе, но на мобильном экране всё выглядит либо слишком плотным, либо слишком воздушным. Причина в том, что одни и те же числовые значения воспринимаются по-разному в зависимости от размера экрана и плотности контента.
Есть два подхода к решению этой задачи.
Первый: единая шкала с адаптивными токенами. В Figma Variables настраиваются Modes, например «Desktop» и «Mobile». Токен spacing-section равен 48px в режиме Desktop и 32px в режиме Mobile. Нейминг остаётся одинаковым, меняются только значения. Разработчик подключает нужный режим через медиазапрос, и вся система переключается автоматически.
Второй: отдельные шкалы для разных платформ. Этот подход оправдан, если мобильное и десктопное приложения сильно отличаются по структуре. Тогда каждая платформа получает свой набор токенов, но базовая единица остаётся общей.
Независимо от подхода, есть несколько практических правил для адаптива:
- Внутренние отступы компонентов (padding кнопок, карточек) обычно не меняются между платформами или меняются минимально.
- Расстояния между секциями на мобайле сокращаются на один шаг шкалы: если на десктопе spacing-7 (48px), на мобайле берётся spacing-6 (32px).
- Горизонтальные поля страницы на мобайле задаются отдельно: обычно это spacing-4 (16px) или spacing-5 (24px) с каждой стороны.
Хорошая проверка: Откройте мобильный макет и посмотрите, сколько контента помещается на первом экране. Если секции занимают слишком много вертикального пространства из-за больших отступов, уменьшите spacing между блоками на один шаг. Если контент слипается, увеличьте. Цель: пользователь должен видеть хотя бы один полный смысловой блок без скролла.
Как согласовать шкалу с командой: практика, а не теория
Создать токены в Figma несложно. Сложнее добиться того, чтобы вся команда использовала их одинаково. На практике разные дизайнеры выбирают разные значения для похожих ситуаций, и через несколько месяцев шкала снова превращается в набор произвольных чисел.
Чтобы этого не происходило, нужны не правила, а договорённости с примерами.
Хорошо работает небольшой внутренний документ или страница в Figma, где для каждого токена показан конкретный пример применения. Не просто «spacing-5 = 24px», а скриншот карточки с подписью «расстояние между заголовком и описанием внутри карточки». Такой документ снимает 80% вопросов при проектировании новых экранов.
Второй инструмент: code review для дизайна. Перед хендофом один из дизайнеров или тимлид проверяет новые компоненты на соответствие шкале. Это занимает 10-15 минут, но предотвращает накопление отклонений.
Третий момент: разработчик должен быть частью процесса с самого начала. Если токены согласованы только внутри дизайн-команды, а разработчик узнаёт о них на хендофе, возникают расхождения в нейминге и логике. Лучше провести короткую встречу на старте и договориться о структуре токенов совместно.
Сравнение подходов к организации шкалы
На практике команды используют разные способы именования и структурирования токенов. У каждого есть свои плюсы в зависимости от размера проекта и состава команды.
| Подход | Пример нейминга | Плюсы | Минусы |
|---|---|---|---|
| Числовой | spacing-1, spacing-2... spacing-8 | Легко масштабировать, нет двусмысленности | Не очевидно, какой шаг для чего |
| Семантический (размеры) | spacing-xs, spacing-sm, spacing-md, spacing-lg | Понятен без документации, удобен в коммуникации | Сложно добавить промежуточные шаги |
| Контекстный | spacing-component-inner, spacing-section, spacing-page | Сразу понятно, где применять | Много токенов, сложнее поддерживать |
| Гибридный | spacing-4 с описанием роли в документации | Баланс между гибкостью и понятностью | Требует актуальной документации |
Для большинства продуктовых команд лучше всего работает гибридный подход: числовые или семантические токены плюс короткое описание роли рядом с каждым значением. Это снижает когнитивную нагрузку без избыточного количества токенов.
Как проверить качество системы отступов перед запуском
Перед тем как передавать макеты в разработку, стоит провести быструю проверку. Она занимает 20-30 минут и помогает поймать отклонения до того, как они попадут в код.
Проверка строится на нескольких вопросах:
- Все ли значения отступов в макете кратны базовой единице? Если нет, это либо ошибка, либо намеренное исключение, которое нужно зафиксировать.
- Используют ли компоненты одного типа одинаковые значения padding? Если кнопки в разных местах макета имеют разный внутренний отступ без причины, это нужно исправить.
- Создаёт ли пространство между блоками визуальную иерархию? Связанные элементы должны стоять ближе, несвязанные - дальше.
- Привязаны ли отступы к токенам, а не заданы вручную? Проверить можно в инспекторе Figma: если рядом с padding стоит имя переменной, а не просто число, всё в порядке.
- Согласована ли шкала с разработчиком? Если токены существуют только в Figma, но не переданы в код, система не работает.
Если все пять пунктов в порядке, система отступов готова к работе. Если нет, лучше потратить час на исправление сейчас, чем разбираться с расхождениями после релиза.
FAQ
Чем spacing-система отличается от сетки?
Сетка определяет layout: колонки, gutters, поля страницы. Шкала отступов работает внутри этой сетки - она регулирует пространство внутри компонентов и между ними. Это разные уровни: сетка задаёт макроструктуру, отступы - микроструктуру.
Обязательно ли использовать 8px? Можно ли взять 10px?
Технически можно, но 10px неудобно масштабируется: 10, 20, 30, 40 - шаги слишком большие для мелких компонентов. Кратность 4 или 8 лучше ложится на стандартные размеры экранов и плотности пикселей. Если очень нужна пятёрка - используй 4px как базу, тогда 20px (5 шагов) вписывается в шкалу.
Как передать spacing-токены разработчику?
Через Tokens Studio или встроенный Dev Mode в Figma. Разработчик видит именованные переменные в инспекторе. Для CSS-проектов токены обычно превращаются в CSS Custom Properties (--spacing-4: 16px), для React Native - в объект с числовыми значениями.
Что делать, если дизайнер хочет 18px, а в шкале нет такого значения?
Это сигнал для обсуждения, а не для исключения. Либо 18px можно заменить на 16px или 20px без потери качества, либо шкала требует нового шага. Если такое значение нужно регулярно - добавь токен. Если это разовый случай - скорее всего, достаточно ближайшего значения из шкалы.
Нужна ли отдельная шкала для мобайла?
Не обязательно отдельная, но адаптация нужна. В Figma Variables можно настроить Modes: один набор значений для десктопа, другой для мобайла, при этом токены называются одинаково. Разработчик использует одно имя, а конкретное значение подставляется в зависимости от брейкпоинта.
Как проверить, что шкала работает правильно?
Открой любой экран и проверь: все отступы кратны базовой единице, нет «случайных» значений вроде 13px или 22px, компоненты одного типа используют одинаковые padding, расстояния между секциями визуально создают иерархию. Если что-то выбивается - это либо ошибка, либо сигнал, что шкала требует нового шага.
Итог
Шкала отступов - это не про красоту и не про перфекционизм. Это про то, чтобы не принимать одно и то же решение снова и снова. Когда значения зафиксированы в токенах и привязаны к компонентам, вопрос «сколько здесь поставить» исчезает сам по себе.
Начать проще, чем кажется: выбери базовую единицу, построй шкалу из 8-9 шагов, создай Variables в Figma и договорись с командой о правилах применения. Это займёт день. А потом просто придерживайся шкалы - и через полгода файл будет таким же чистым, каким был в первый день.