Привет! Я Захар, дизайнер мобильных приложений. Уже больше 3-х лет я делаю UI-киты и небольшие дизайн-системы для приложений. За это время получилось сделать удобную и гибкую систему, которая экономит время разработки и уменьшает расхождение макетов с продом минимальными усилиями.
В этой статье расскажу как сделать, применить и передать в разработку токены цветов для мобильного приложения. Позже напишу ещё про токены размеров, типографику и в целом подготовку макетов.
Создание цветов
Для начала надо определиться с группами цветов, которые нужны:
Primary — основные действия на экране, например кнопка «В корзину». Обычно в основе лежит брендовый цвет. Нужно всегда;
Secondary — вторичные действия на экране. Нужно только если есть два брендовых цвета или нужно чёткое разделение основных действий, например «В корзину» и «Купить сейчас»;
Error — различные ошибки и действия удаления. Нужно всегда;
Success — различные подтверждения или уведомления об успехе. Нужно только если Primary не подходит (например, если он красный)
Surface — поверхности и объекты на них. Нужно всегда;
Disabled — неактивные состояния элементов. Нужно всегда.
Это базовые группы, которых будет достаточно для отрисовки всего UI в большинстве проектов. По необходимости можно добавлять свои, кастомные группы.
Теперь выбираем один базовый цвет для каждой базовой группы, чтобы было от чего отталкиваться:
Primary и secondary это брендовые цвета (обычно они на логотипе), если их нет, то у вас есть возможность выбрать любые.
Error должен быть красным, success зелёным, можно сделать их ярче или темнее в зависимости от общего стиля приложения.
Surface это белый, чистый или с небольшой примесью primary.
Disabled серый.
Теперь в каждой группе создаём токены.
У primary, secondary, error и success будет одинаковый подход для базового набора:
[name] — сам цвет, пример: primary, secondary и тд;
active_[name] — цвет [name], когда с ним взаимодействуют. Например, когда жмут на кнопку. Пример: active_primary;
on_[name] — цвет элемента, который находится на основном цвете. Пример: on_primary;
[name]_container — более спокойный вариант цвета, для второстепенных действий или поверхностей. Пример: primary_container;
active_[name]_container — цвет [name]_container, когда с ним взаимодействуют, пример: active_primary_container;
on_[name]_container — цвет элемента, находящегося на [name]_container. Пример: on_primary_container.
Базовый набор для surface:
surface_low
surface
surface_high — уровни поверхностей;
on_surface — элементы на поверхности;
on_surface_variant — вторичные элементы на поверхности;
inverse_surface — инвертированная поверхность, т.е. тёмная при светлой теме;
inverse_on_surface — элементы на инвертированной поверхности.
Базовый набор для disabled:
disabled_low
disabled
disabled_high — уровни элементов в неактивных объектах.
Это стандартный набор, в нём название каждого токена связано с его применением. Например primary используется для главного элемента на экране, к которому надо привлечь внимание (вроде кнопки «В корзину»). А on_primary для объектов, которые лежат на primary (буквально на_примари в переводе), т.е. это будет текст на кнопке «В корзину».
Стандартный набор токенов можно расширить любыми необходимыми токенами. Например [name]_stroke только для обводок или [name]_variant если просто нужен вариант цвета, без конкретного применения. Если нужен цвет с прозрачностью, то создаём токен [token]_aa, где aa это значение прозрачности в процентах, пример: on_primary_50.
Теперь всем этим токенам надо назначить цвета. Для этого берём основной цвет для каждой группы, включаем режим цвета HSL и меняем только последнее значение.
Для токенов, которые вы будете добавлять самостоятельно, можете использовать любые значения, даже повторяющиеся. Главное чтобы:
У всех токенов были уникальные названия;
Если цвета должны находиться друг над другом, между ними должно быть минимум 49 единиц ligtness, для сохранения контрастности.
Таким образом внутри каждой базовой группы токенов у нас получается набор оттенков одного цвета (с одинаковыми hue и saturation, но различными lightness значениями).
Если в приложении есть, например, статусная модель и для каждого статуса нужен свой, определённый цвет, можно создать кастомную группу и добавить в неё нужные цвета. В идеале ещё уточнить у разработки, как статусы называются у них, чтобы подружить названия в фигме и коде.
Практическая часть
По шагам, что происходит на видео:
Открываем в фигме Variables
Создаём группу color/semantics
Создаём группу primary и в ней токен primary. При наличии «/» в названии токена создаётся группа
Устанавливаем цвет для токена
Копируем токен, переименовываем и назначаем цвета изменяя ligtness по таблице выше
Дублируем группу и создаём из неё другие группы цветов, назначаем названия и цвета у токенов
Готово.
Теперь при создании макетов пользуемся только токенами. Если нужен новый цвет — заводим новый токен.
Примитивы - Семантика - Компоненты
Сейчас мы создавали семантический уровень. На нём лежат токены с человекочитаемыми названиями, которые применимы во всём приложении.
Для информации — в более сложных системах с несколькими продуктами ещё создают примитивный уровень, который хранит в себе цвет и передаёт его в семантический уровень. Чтобы при создании семантического уровня под отдельную платформу базовая палитра была единой. В нашем случае это избыточно, так как продукт один, но если будет интерес, напишу пост в тг канале.
Кроме примитивов и семантики ещё есть компонентный уровень. Он пригодится, если у вас проект с активной поддержкой и есть время на создание ещё бо́льшего числа токенов. На компонентном уровне создаются группы токенов для каждого компонента — кнопки, чекбокса, инпута и тд. После релиза вы сможете изменить внешний вид конкретного компонента как в фигме, так и в коде в очень короткие сроки, практически не задействуя разработку.
Компонентный уровень
Если вы решили, что вам всё же нужен компонентный уровень, создайте в Variables папку color/components и внутри создавайте группу под каждый простой компонент из UI-кита. Внутри группы создавайте токены под каждый элемент в каждом состоянии и назначайте ему цвет из семантики.
Выше пример токенов для простой кнопки, у которой есть фон, текст и 4 состояния. Для каждого элемента в каждом состоянии я создал по токену и назначил ему цвет из семантики. Для текста сделал только два состояния, т.к. во всех случая, кроме одного, он не меняется (и не должен), поэтому решил сэкономить пару токенов (это упрощает проектирование и разработку).
После создания токенов применяем их к самому компоненту на макете и выключаем все чекбоксы видимости, чтобы они не мешали в дальнейшей работе.
В создании компонентного уровня нет ничего сложного, зато он даёт много гибкости в системе. И если его не сделаете вы, его сделают разработчики у себя в коде. И вы будете только догадываться, что там происходит.
До передачи разработке
Общая рекомендация для всех уровней — следить за длинной токенов, учитывая уровни вложенности. В фигме токены выглядят красиво и понятно за счёт древовидной структуры, можно создать кучу групп и аккуратно всё по ним разложить. Но в коде название токена содержит все уровни дерева одной строкой. И если не контролировать, то можно получить токены на 100+ символов, где хватило бы 10-20.
Так же не пропускайте никаких слоёв на макете (кроме системных элементов). Это важно, чтобы подход работал и программисты не матерились при вёрстке (хотя бы поменьше).
Зачем передавать в разработку?
Казалось бы, вот же все цвета в фигме лежат, вроде работа дизайнера сделана и всё окей. Но дальше с цветами будет примерно следующее:
Если разработчик найдёт цвета (скорее всего не найдёт, Variables видно только на Design доступе), то он как-то эти цвета вытащит (скорее всего ручками, т.к. плагины в фигме для разработчиков недоступны/неизвестны), потратит на это КУЧУ времени и дальше будет как-то это обновлять. Или не будет обновлять, пока вы с пипеткой не пройдётесь по всему проду и не распишите багу.
Поэтому лучше взять выгрузку на себя. Это займёт минут 10–20, но сэкономит часы разработки (они пока пусть лучше фичи пилят), уменьшим вероятность ошибки в цветах и потом сможем легко всё менять как захотим. А заодно подружимся с разработчиками.
Передача в разработку
Для передачи надо вытащить токены из фигмы в текст с помощью плагина. Я пользуюсь variables2json, но можно и любым другим, который соблюдает требования:
1. Цвета с прозрачностью пишутся в формате 00000080, а не 0, 0, 0, 0.5;
2. Названия токенов написаны полностью, со всей вложенностью.
В плагине получаем в текстовом виде переменные для семантического и компонентного уровня.
Дальше нам понадобится текстовый редактор. Можно обойтись блокнотом, заметками или фигмой, но я рекомендую Sublime, так как в нём всё будет быстрее, удобнее и бесплатно. Sublime это в целом очень функциональная программа для работы с текстом и кодом, но чтобы не грузить лишним, я покажу только небольшую часть, которая будет нам нужна.
После установки открываем Sublime и создаём файл (File → New File). Вставляем в него текст, который получили в плагине.
Сейчас в коде много лишнего текста, который ничего не значит и никому не нужен. В Sublime его можно быстро убрать (описание ниже).
Лишний код убирается в 6 нажатий:
1. Выделяем лишний код;
2. ctrl+с — копируем лишний код;
3. ctrl+f — активируем поиск;
4. ctrl+v — вставляем лишний код;
5. alt+enter — выделяем все найденные результаты;
6. backspace — стираем всё выбранное.
Повторяем со всем лишним, пока код не будет выглядеть вот так на семантическом уровне:[token_name] “#[hex_code]”
И так на компонентном:[token_name] “[token_name]”
Потом убираем лишнее название группы в начале (primary/primary → primary). Для этого так же жмём ctrl+f, пишем primary/primary, жмём alt+enter и пишем primary. Повторяем со всеми группами.
И так же заменяем везде «/» на «_». так как с точки зрения кода у нас тут нет вложенности, а есть только уникальное имя для каждого токена.
В целом мы уже сделали достаточно для передачи разработке, можно скопировать получившийся результат и со спокойной совестью отдать его разработке. Но я рекомендую пойти ещё дальше и привести код к нужному формату. Так будет проще передавать обновления и меньше риск ручной ошибки разработчика.
Для этого идём к разработчикам и просим у них написать строку для стиля цвета, с hex значением (для семантики) и alias значением (для компонентного уровня).
Привет, хочу подготовить тебе цвета приложения. Можешь плиз показать формат для стиля цвета, который хранит в себе hex. И для стиля, который ссылается на этот стиль (alias).
Например:
on_primary_a50 “#00000080”
и
button_primary_loading_text “on_primary_a50”
Разработчики должны будут отправить примерно такое для Android:<color name="primary">#80000000</color><color name="button_primary_loading_text">@color/on_primary_a50</color>
И примерно такое для iOS:static let _primary = UIColor.hex("8000000")
static let buttonPrimaryLoadingText = UIColor._onPrimaryA50
Если нет возможности связаться с разработчиком, то можете взять из примера выше. Но я настоятельно рекомендую уточнить, так как в зависимости от проекта и разработчика написание может меняться.
Обратите внимание, что обычно в дизайне для обозначения прозрачности цвета его пишут в формате #RRGGBBAA, где к обычному hex значению добавлена прозрачность в конце – AA (см таблицу). Но программы разработки зачастую требуют #AARRGGBB, где прозрачность в начале. Обсудите с вашими программистами, как вам будет удобнее.
Преобразовывать будем в ChatGPT. Запрос примерно:
Приведи строки к такому виду по примеру:
[строка от разработчика. Для семантики первая строчка, для компонентов вторая]Строки:
[сюда вставляем то, что лежит в Sublime. Возможно придётся идти по частям из-за ограничений на символы]
Вставляем в файл Sublime то, что выдаёт ChatGPT, сохраняем файл и называем его colors_android_v0.1.json
Теперь делаем всё тоже самое для iOS, только добавляем в запрос фразу «И переведи значения в camelCase из snake_case» и файлик называем colors_ios_v0.1.json
Файлы сохраняем и кидаем разработчикам, просим их перепроверить, спрашиваем всё всем ли ок по формату, нужны ли какие-то ещё комментарии или что-то поправить по структуре. Когда от каждого разработчика получаем ок, можно гордо в названии файла поставить v1.0 и теперь это ваша точка отсчёта. После этого желательно не менять названия токенов и логику их расположения без согласования с разработкой, так как им придётся много чего переделывать.
Если далее понадобится что-то изменить, надо будет изменить значение в фигме и в нужной строчке в коде. Если добавить — добавляем в фигму и строки в код. Если строк мало, можно даже дописать вручную, это будет быстрее.
Вот как-то так
И в Variables разобрались, и программистами себя ощутили, и получили пользу от нейросетей. Делитесь мнением в комментариях, отправляйте статью коллегам и подписывайтесь на канал в телеграм, чтобы не пропустить обновления и другие статьи из цикла.
basn63
красаучег, люблю порядок