23 мая 2025 г.·7 мин чтения

Мобильные дизайн-токены, когда web-продукт постоянно меняется

Узнайте, как мобильные дизайн-токены помогают iOS и Android оставаться в одном стиле с быстро меняющимся web-продуктом — через правила именования, привязку к компонентам и простые проверки.

Мобильные дизайн-токены, когда web-продукт постоянно меняется

Почему стили расходятся, когда web меняется быстрее mobile

Web-продукты меняются понемногу, но постоянно. У кнопки становится мягче радиус, заголовок темнеет, на странице тарифов уплотняются отступы. Команда web может выкатить это за несколько часов. Команда mobile обычно работает по более длинному циклу, поэтому старые визуальные значения ещё днями или неделями остаются в приложении.

Этот разрыв и создаёт дрейф. Обычно всё начинается с хороших намерений. Кто-то видит новый брендовый цвет в Figma, вручную переносит hex-значение в iOS, затем другой человек на глаз меняет отступы в Android, и никто не замечает, что обе команды немного по-разному поняли одно и то же изменение. После нескольких таких итераций приложение всё ещё похоже на бренд, но уже не совсем точно.

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

Одни и те же паттерны повторяются снова и снова:

  • Web каждую неделю выпускает небольшие визуальные правки.
  • Mobile продолжает жить со старыми значениями до следующего окна релиза.
  • Дизайнеры и разработчики вставляют сырые значения вместо обновления общих токенов.
  • Нативные элементы используют стандартные настройки платформы, которые сначала выглядят нормально, а потом уезжают от бренда.

У таких нативных значений по умолчанию есть одна особенность: проблемы они скрывают дольше, чем ожидают люди. Сегментированный переключатель, тумблер, таб-бар или текстовое поле могут выглядеть приемлемо в разработке, потому что они похожи на платформу. Но потом поздняя проверка сравнивает их с последними web-экранами, и расхождения всплывают сразу все. Шрифт слишком лёгкий. Внутренний отступ чуть не тот. Состояние нажатия всё ещё использует старый цвет.

Именно поэтому мобильные дизайн-токены так важны для быстро меняющихся продуктов. Они превращают решения по бренду в именованные значения, которыми могут пользоваться обе платформы, вместо того чтобы заставлять каждого разработчика помнить последние визуальные правила.

Если команда пропускает этот слой, дрейф стиля превращается в еженедельную уборку. Никто не делает одну большую ошибку. Люди допускают много маленьких, и приложение постепенно перестаёт выглядеть как тот же самый продукт, который люди видят в web.

Что должно входить в набор токенов

Хороший набор токенов достаточно небольшой, чтобы его можно было понять, и достаточно широкий, чтобы покрывать UI, который вы выпускаете каждую неделю. Если он превращается в склад всего на свете, команда перестанет ему доверять. Мобильные дизайн-токены работают лучше всего, когда в них лежат повторяющиеся решения, а не каждый пиксель на каждом экране.

Начните с двух слоёв. Базовые токены хранят простые значения: брендовый синий, gray 100, spacing 8, radius 12, font size 16, motion 200ms. Семантические токены описывают задачу: основной текст, фон экрана, заливка кнопки, граница карточки, опасное состояние. Это разделение важно, потому что изменения бренда обычно сначала затрагивают базовый слой, а продукт при этом продолжает использовать те же семантические названия.

В базовый набор должны входить те части, которые люди замечают снова и снова. Обычно это цвет, типографика, отступы, радиус, границы и движение. Если дизайнер или разработчик выбирает что-то из этого вручную больше одного раза, это, скорее всего, нужно вынести в систему.

Для цвета мало просто брендовой палитры. Добавьте сценарии для текста, фона, поверхности, границ, успеха, предупреждения и ошибки. Для типографики нужны размер, межстрочный интервал и насыщенность для тех текстовых стилей, которые вы реально используете. Отступы должны идти по шкале. Радиус и толщина рамок должны оставаться ограниченными. Анимации должны определять длительность и плавность для типичных действий, например открытия листа или подтверждения нажатия.

Пропишите, где должен использоваться каждый семантический токен. Простыми словами. Например, "surface-primary" может быть для карточек и фонов модальных окон, а "text-muted" — для вспомогательного текста и второстепенных подписей. Такая короткая заметка убирает догадки, а именно с догадок и начинается дрейф стиля.

Оставьте рекламные иллюстрации, сезонные промо и разовые графические элементы отдельно от набора токенов. Праздничный градиент для одного экрана — это не базовое правило. Лучше держать такие стили рядом с фичей, которая их использует, а потом удалять, когда кампания заканчивается.

Есть и простой тест. Если бренд-команда меняет один синий оттенок, а кнопки, ссылки, вкладки и бейджи после нескольких обновлений токенов всё ещё выглядят уместно, значит набор работает. Если команде приходится вручную просматривать десятки экранов, набор слишком расплывчатый или слишком смешанный.

Давайте токенам имена так, чтобы изменения бренда были небольшими

Команды сами создают себе лишнюю работу, когда названия токенов описывают текущий цвет, а не то, какую задачу он выполняет. Если токен называется blue-500, любое обновление бренда превращается в переименование, поиск или и то и другое. Если он называется surface-primary, можно просто изменить значение и почти не трогать код приложения.

Хорошие названия описывают роль, контраст или состояние. text-muted сразу говорит, как этот текст должен читаться на экране. surface-primary показывает, где должен использоваться цвет. Дизайнер может в одном релизе перевести этот токен из синего в сливовый, а мобильное приложение при этом останется логичным.

Старайтесь, чтобы структура названий была похожа в web и mobile. Если в web используется text-muted, в mobile не стоит придумывать secondaryLabelSoft, если только платформе это действительно не нужно. Похожие названия уменьшают объём адаптации, снижают количество ошибок и ускоряют проверку, потому что все говорят об одном и том же наборе токенов.

Обычно лучше работает небольшой набор, а не слишком умный. Начните с групп, которыми люди пользуются каждый день:

  • Surface-токены для страницы, карточки, приподнятых областей и брендовых поверхностей
  • Text-токены для обычного, приглушённого, инвертированного и ошибочного текста
  • Border-токены для тонких линий, заметных разделителей и ошибок
  • Action-токены для основных, вторичных и разрушительных действий

Состояния тоже нуждаются в названиях. Команды часто помнят цвет кнопки по умолчанию, но забывают, что происходит, когда пользователь нажимает её, теряет доступ или получает ошибку в форме. Добавляйте токены состояний осознанно, например action-primary-pressed, action-primary-disabled и text-error.

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

Например, команда с green-button-text и green-button-bg будет трогать много файлов, когда маркетинг заменит зелёный на коралловый. А команда с action-primary-label и action-primary-surface просто обновляет значения токенов, проверяет контраст и идёт дальше. Именно поэтому мобильные дизайн-токены так важны: обновления бренда остаются локальными и не расползаются по всем экранам.

Поэтапно привязывайте токены к нативным компонентам

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

Используйте один источник для значений токенов. Это может быть файл токенов, экспорт из дизайна или небольшой общий пакет, но это должна быть единственная точка, где живут цвет, размер шрифта, радиус, отступы и уровень тени. Если iOS читает одну копию, а Android — другую, дрейф стиля начинается почти сразу.

Практичный план внедрения выглядит так:

  • Выберите 5–8 распространённых компонентов и временно оставьте их текущие стили без изменений, пока вы их пересобираете.
  • Создайте тонкие обёртки в iOS и Android, например AppButton, AppInput и AppCard.
  • Подключите эти обёртки к одним и тем же названиям токенов, даже если каждая платформа визуально рендерит их немного по-разному.
  • Заменяйте старые компоненты экран за экраном, а не пытайтесь переписать всё приложение за один заход.
  • Сравнивайте скриншоты до и после для каждого экрана, а потом исправляйте мелкие расхождения до слияния.

Эти обёртки важнее, чем кажется многим командам. Они дают одно место, где брендовые токены превращаются в нативное поведение. Например, токен для основной кнопки может перейти в конфигурацию UIButton на iOS и в Material-компонент на Android. Название токена остаётся тем же. А код под ним может следовать правилам каждой платформы.

Меняйте компоненты небольшими партиями. Checkout, onboarding и settings обычно быстро показывают проблемы со стилями, потому что там смешаны текст, формы, кнопки и состояния ошибок. Если экран всё ещё использует жёстко заданные hex-цвета или кастомные отступы, исправляйте это в том же проходе. Если оставить такие куски, они быстро накапливаются.

Проверка скриншотов помогает ловить мелкие несоответствия, которые люди замечают позже. Поставьте старые и новые изображения рядом и проверьте размер текста, отступы, радиус углов, состояния disabled и контраст. Десять минут визуальной проверки могут сэкономить часы еженедельной уборки.

Осознанно учитывайте различия между платформами

Привяжите токены к компонентам
Превратите кнопки, поля, карточки и вкладки в общие нативные компоненты.

Хорошие мобильные дизайн-токены создают один общий язык для iOS и Android. Названия должны оставаться одинаковыми, даже если итоговый интерфейс не рендерится абсолютно идентично. Если меняется брендовый цвет, вы хотите обновить color.surface.brand один раз, а не искать его в двух разных системах.

Но это не значит, что обе платформы должны выглядеть одинаково до пикселя. У нативного интерфейса есть собственные правила. Текст, зоны нажатия, тени и верхние отступы ведут себя по-разному, и пользователи сразу замечают, когда приложение спорит с платформой вместо того, чтобы естественно в неё вписываться.

Чаще всего команды спотыкаются на тексте. Токен для основного текста может быть 16 на обеих платформах, но нативное поведение шрифта всё равно может сделать одну сторону визуально плотнее или свободнее. На iOS часто нужен другой межстрочный интервал, чем на Android. Ещё важны динамический размер текста и масштабирование шрифта. Если слишком жёстко их переопределять, приложение может выглядеть аккуратно на скриншотах и неудобно в реальном использовании.

С отступами нужна такая же аккуратность. Внутренние отступы контента и отступы устройства — это не одно и то же. Промежуток между карточками в 16 — это дизайнерское решение. Верхний safe area или системный inset — это ограничение устройства. Держите это раздельно в модели токенов, иначе инженеры начнут добавлять разовые padding-значения просто чтобы заголовки и таб-бар не сталкивались.

Практичная схема выглядит так:

  • Держите общие названия токенов для обеих платформ.
  • Добавляйте небольшие platform aliases только там, где есть реальные нативные различия.
  • Дайте нативному масштабированию текста поработать, прежде чем добавлять ручные исправления.
  • Определяйте safe area и отступы системной панели как отдельные токены.
  • Храните каждое исключение в одном слое сопоставления.

Последний пункт очень помогает при уборке. Когда исключения живут внутри кода экрана, они быстро размножаются. Один разработчик добавляет смещение заголовка только для Android. Другой — дополнительный отступ в iOS для модального окна. Через месяц никто уже не помнит, какие значения относятся к бренд-системе, а какие являются локальными костылями.

Лучший подход скучный, и в этом его сила. Держите общие токены стабильными. Держите platform aliases небольшими. И храните все исключения в одном месте. Тогда обновление бренда меняет приложение один раз, а нативные различия остаются под контролем и легко проверяются.

Простой пример обновления бренда

Обновление бренда на бумаге обычно выглядит небольшим, а в приложениях превращается в хаос, если команда правит всё экран за экраном. Маркетинг выбирает новый основной цвет, меняет радиус углов с 8 на 12 и ожидает, что уже в следующем релизе всё будет выглядеть обновлённым.

Команда web обычно начинает первой. Она не перекрашивает каждую кнопку вручную. Она меняет семантические токены вроде action-primary-bg, action-primary-text и control-radius, а затем библиотека компонентов сама подхватывает новые значения.

Mobile должен идти тем же путём. Если мобильные дизайн-токены настроены хорошо, команда меняет источник токенов один раз и не трогает отдельные экраны. В этом и смысл: изменить значение в одном месте, а не перекрашивать всё в пятидесяти местах.

Допустим, старое приложение использовало ярко-синий для основных действий. Новый бренд — более мягкий фиолетовый, а скруглённые элементы теперь стали частью визуального стиля. Мобильная команда обновляет общий файл токенов, а затем подключает эти значения к нативным компонентам:

  • Кнопки берут новый фон, цвет текста и радиус
  • Чипы используют тот же радиус, но более спокойный фон
  • Поля ввода сохраняют свои токены для границы и заливки, но принимают новый радиус элементов
  • Состояния disabled остаются отдельными, чтобы они не становились слишком яркими или слишком слабоконтрастными

Именно здесь команды чаще всего ошибаются. Кто-то обновляет основную кнопку и забывает про кнопку с обводкой. Другой человек вручную подправляет чипы, потому что они "чуть-чуть не совпадают". Через неделю в приложении уже три оттенка фиолетового и два варианта радиуса углов.

Короткая QA-проверка ловит большую часть такого дрейфа. Проверяйте очевидные экраны, но не забывайте и про состояния, которые люди часто пропускают:

  • Тёмная тема
  • Отключённые кнопки и поля ввода
  • Состояния нажатия и фокуса
  • Ошибки в полях
  • Смешанные экраны со старыми закэшированными компонентами

Привязка нативных компонентов работает лучше всего, когда команда воспринимает компоненты как потребителей токенов, а не как владельцев стиля. Тогда обновление бренда превращается в небольшое изменение источника плюс аккуратную QA-проверку, а не в уборку, которая возвращается каждую пятницу.

Ошибки, из-за которых уборка становится еженедельной

Уберите жёстко заданные стили
Замените сырые цвета и отступы токенами, которые команда сможет поддерживать.

Еженедельная уборка обычно начинается с простой ошибки: команды вставляют сырые брендовые значения прямо в экраны. Новый hex-цвет приходит от команды web, и кто-то по одному обновляет кнопки, бейджи и заголовки. На день это кажется быстрым решением. Через месяц никто уже не знает, какой синий — актуальный.

Мобильные дизайн-токены помогают только тогда, когда экраны ссылаются на токены, а не на сырые цвета, размеры шрифта или радиусы углов. Если дизайнер кладёт брендовые значения прямо в макет, инженеры часто копируют те же значения в код. И тогда каждое обновление бренда превращается в поисковую операцию.

Ещё одна медленная утечка — это названия. Дизайнеры могут называть токен "brand-primary", а разработчики — buttonBlue или mainActionColor. Смысл у них один и тот же, но из-за несоответствия появляется догадка. Догадки создают исключения, а исключения накапливаются.

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

Тёмную тему часто оставляют напоследок, потому что светлая кажется основной задачей. Обычно это удваивает объём уборки. Сначала команда выкатывает новую светлую тему, а потом по-быстрому допиливает тёмную с помощью разовых исправлений. В итоге получаются карточки, поля и пустые состояния, которые почти совпадают, но не совсем.

Последняя ловушка — пропускать проверку компонентов после правки токенов. Одно изменение токена может задеть гораздо больше, чем ожидает команда. Небольшое обновление отступов или цвета текста способно нарушить вкладки, уведомления и состояния форм по всему приложению.

Более безопасный ритм скучный, и именно поэтому он работает:

  • Сначала сопоставляйте сырые брендовые значения с семантическими токенами
  • Держите одну общую систему названий для дизайна и кода
  • Переименовывайте токены редко и только по понятной причине
  • Выпускайте светлые и тёмные обновления вместе
  • Проверяйте реальные компоненты после каждого изменения токена

Команда, которая делает эти пять вещей, тратит меньше времени на ежепятничное исправление мелких визуальных несоответствий.

Быстрая проверка перед каждым релизом

Внедряйте изменения безопасно
Пересобирайте общие компоненты небольшими партиями, не срывая работу над дорожной картой.

Проверка перед релизом должна занимать около 15 минут. Если дольше, значит слой токенов, скорее всего, слишком расплывчатый, и команда чинит экраны вручную вместо того, чтобы чинить источник.

Поставьте рядом пять самых часто используемых экранов в web и mobile. Не сравнивайте все страницы. Сравнивайте те экраны, которые люди открывают каждый день, потому что мелкие расхождения на них ощущаются сильнее, чем редкие пограничные случаи. Смотрите на размер текста, форму кнопок, цвет поверхности, радиус углов и толщину иконок. Когда что-то кажется не так, возвращайтесь к токену или к сопоставлению нативного компонента.

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

Изменения состояний тоже нужно проверять руками. Нажмите кнопки в состоянии pressed. Откройте экраны, где действия отключены. Специально вызовите понятную ошибку, например неверный email или пустое обязательное поле. Если эти состояния используют жёстко заданные цвета или отступы, дрейф дизайн-системы проявится быстро.

Отдельно стоит смотреть на отступы, потому что они уезжают незаметно. Чаще всего первыми расходятся формы и карточки. На одном экране под подписью стоит 12 px, на другом — 16, а в теле карточки во время срочного фикса появляется кастомный margin. По отдельности это не выглядит драматично. Вместе — делает приложение менее доведённым, чем его web-версия.

Короткая проверка помогает:

  • сравнивать скриншоты реальных экранов, а не отдельных компонентов
  • тестировать один путь в светлой теме и один — в тёмной
  • нажимать pressed-, disabled- и error-состояния
  • проверять строки формы, отступы карточек и расстояния до вспомогательного текста
  • удалять старые токены или осознанно привязывать их к актуальным названиям

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

Что делать дальше команде, которая хочет меньше дрейфа

Команды обычно ошибаются, когда пытаются исправить всё сразу. Начните с нескольких нативных компонентов, которые есть почти на каждом экране. Это даст вам небольшую зону для проверки и быстро покажет, достаточно ли понятны ваши мобильные дизайн-токены.

Практичный первый набор:

  • buttons
  • inputs
  • cards
  • text styles

Если эти четыре элемента остаются синхронизированными, большинство обновлений продукта перестаёт превращаться в уборку. Изменение цвета кнопки, новый радиус углов или корректировка масштаба текста должны проходить через общие токены, а затем попадать в эти компоненты. Если изменение всё ещё требует ручных правок в десяти местах, модель ещё не готова.

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

Относитесь к изменениям токенов так же, как к изменениям продукта. У каждого изменения должен быть владелец, короткое объяснение и заметка к релизу. Отслеживайте, когда поменялся токен, какие компоненты его используют и должны ли iOS и Android совпадать или отличаться намеренно. Простая запись всегда лучше памяти.

Ещё полезно ввести одно правило: никаких прямых стилей в экранах, если команда не договорилась, что это разовый случай. Это звучит жёстко, но сильно сокращает переделки. Когда дизайнеры обновляют бренд, команда сначала меняет набор токенов и общие нативные компоненты. Экраны наследуют изменения, а не спорят с ними.

Небольшая команда может настроить это за одну-две недели. Большой команде, возможно, понадобится больше уборки, особенно если старые экраны уже смешали жёстко заданные значения с общими стилями.

Если ваша команда постоянно упирается в названия токенов, привязку нативных компонентов или правила платформ, внешний взгляд может сэкономить много времени. Oleg Sotnikov может как Fractional CTO проверить вашу модель токенов и план нативных компонентов, а затем показать, где дрейф будет возвращаться снова и снова, если не изменить структуру.