Spacing-система в интерфейсе: как задать отступы один раз и не трогать их снова

Spacing-система в интерфейсе: как задать отступы один раз и не трогать их снова

Коротко:

  • Хаос в отступах почти всегда начинается с одного и того же: каждый компонент проектируется отдельно, без общей базовой единицы.
  • Рабочая основа - кратность 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-14pxИконка рядом с текстом, метка над полем
spacing-28pxВнутренний отступ маленького компонента, gap между иконками
spacing-312pxPadding кнопки по вертикали, отступ внутри тега
spacing-416pxСтандартный padding карточки, отступ между строками списка
spacing-524pxРасстояние между группами элементов внутри блока
spacing-632pxОтступ между секциями внутри экрана
spacing-748pxКрупные блоки, разделители между секциями страницы
spacing-864pxОтступы между крупными секциями лендинга или дашборда

Названия токенов могут быть числовыми (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».

Процесс выглядит так:

  1. Открываешь панель Variables (Edit - Local Variables).
  2. Создаёшь коллекцию «Spacing».
  3. Добавляешь переменные типа Number: spacing-1 = 4, spacing-2 = 8 и так далее.
  4. Привязываешь переменные к 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 и договорись с командой о правилах применения. Это займёт день. А потом просто придерживайся шкалы - и через полгода файл будет таким же чистым, каким был в первый день.