Сравнение популярных дизайн систем | Переменные цвета
Вы, вероятно, уже читали много статей о том, как создавать цветовые переменные в дизайн-системах и UI-китах. Я тоже прошёл через этот этап, но потом, попав в какую-нибудь дизайн-систему, терялся. Дизайн-системы не прощают ошибок: если на финальном этапе вдруг захочется переделать какую-то часть, это обойдётся дорого, займёт много времени и придётся признавать ошибку. Я не люблю ошибаться.
Я открыл все популярные дизайн-системы и начал сравнивать их между собой, записывая различия. Надеюсь, что эта статья сбережёт вам время, которое может уйти на самостоятельный разбор. Расскажу о разных путях, которыми можно пойти при работе с цветами, и заодно поделюсь несколькими любопытными моментами.
Вы прочитаете эту статью примерно за 14 минут
Прежде чем начать, парочка уточнений
Z-index отвечает за порядок расположения элемента и его дочерних слоёв по оси Z. Проще говоря, если у элемента более высокий z-index, он перекрывает те объекты, у которых этот показатель ниже. Это свойство даёт возможность управлять тем, что будет на переднем плане, а что скроется за другим элементом.
Есть два типа построения цвета в дизайн-системах:
1. От объекта (например, Background, Text, Icon) — как в Carbon (IBM), Ant Design, Gravity UI (Яндекс) и Paradigm (VK).
2. От положения объекта (передний или задний план) — как в Material 3 (Google) и Fluent 2 (Microsoft).
Если пока что это звучит не совсем ясно — не переживайте: дальше будут картинки, которые всё наглядно покажут.
Carbon Design System (IBM)
При знакомстве с дизайн-системой Carbon (учитывая, что в работе я её не использую) у меня возникли вопросы, как именно применяются цветовые токены. Документация не предлагает наглядных примеров, поэтому приходилось догадываться о некоторых моментах самостоятельно. Тем не менее, я смог сделать несколько выводов.
У Carbon цвет строится «от объекта»
Например есть категория Text, в которой собраны все возможные переменные цвета, предназначенные именно для текста.
У Carbon есть несколько «базовых» категорий: Background, Layer, Border, Text и Icon. Помимо этого, предусмотрены дополнительные группы, например Field, Button и прочие.
Особенно интересна категория Miscellaneous: это своего рода «костыль», куда отправляют те цвета, которые не вписываются в основную логику построения.
Примитивы у Carbon вынесены в отдельный файл: это базовые цветовые переменные, которые ещё и делятся по состояниям (Default и Hover). Кроме того, каждый оттенок идёт с градацией по насыщенности — от 10 до 100 (к примеру, Default/Blue/50).
С точки зрения разных состояний у каждого типа цвета предусмотрена отдельная переменная: к названию токена просто добавляется нужное состояние (например, button-secondary-hover).
Это, пожалуй, самый базовый и понятный подход к составлению цветов в дизайн-системе. Однако, на мой взгляд, он довольно громоздкий. Например, все слои (Layer-01, Layer-02, Layer-03) в состоянии Hover ссылаются на один и тот же примитив (Hover/Gray/10) и при этом находятся в одной категории. В результате для 3 слоёв нужно 17 переменных.
Material 3 (Google)
В Material 3 есть наглядные примеры: в пару кликов можно наложить разные темы и сразу увидеть, как меняются и сочетаются цвета. Это довольно удобно, особенно когда нужно оценить работу системы в динамике.
Цвета здесь делятся на две основные группы: Schemes (для объектов) и State Layers (прозрачные оттенки, которые накладываются поверх объектов).
В Material 3 семантические названия цветов идут напрямую от их Hex-кода — отдельного уровня примитивов здесь нет.
Нейминг слоёв в Schemes зависит от положения объекта (например, Primary/On Primary, Error Container/On Error Container). Приставка «On» говорит о том, что элемент располагается на переднем плане.
В State Layers названия носят технический характер и указывают на уровень прозрачности слоя (например, Opacity-08, Opacity-16). Эти переменные применяются в дополнительном слое «State-Layer», который накладывается поверх базовых цветов. Я думаю такой подход удобно использовать для создания различных состояний.
Эта система неймингов выглядит заметно проще и логичнее, во многом благодаря вынесению состояний в отдельную категорию. Единственное, что может вызывать вопросы, — то, что не все переменные вписываются в такую логику. Например, переменная для Border не может иметь состояния «On». Кроме того, в Material 3 редко применяют наложения нескольких поверхностей друг на друга, поэтому нет необходимости использовать слои с привязкой к оси Z, как это сделано в Carbon
Fluent 2 (Microsoft)
В Fluent 2 для каждого компонента есть собственные примеры, что само по себе доставляет отдельное удовольствие — всё наглядно, и сразу видно, как работают те или иные цвета.
Переменные разделены на примитивы (Global) и семантику (Theme).
Neutral включают нейтральную гамму оттенков — от белого до чёрного — которая служит основой для дальнейшей настройки.
Alpha включает варианты с различной степенью прозрачности для белого, чёрного и серого оттенков.
У Shared есть очень интересная концепция. Берётся один основной цвет, а остальные оттенки формируются на его основе и получают соответствующие названия. Для цветовых растяжек это смотрится весьма логично и понятно.
В Themes реализовано нестандартное разделение по z-index: «1» считается самым верхним и важным уровнем контента, а все остальные располагаются «ниже».
Например, у основной кнопки цвета распределены так: для её подложки используется Brand/Background/1/Rest, а для текста и иконки — Neutral/Foreground/1/Rest.
Кстати, «обычное» состояние называется нестандартно: вместо «Default» используется «Rest».
На мой взгляд, подобная система категоризации — один из самых понятных вариантов. Да, z-index тут идёт зеркально, но разобраться в логике и воспроизвести её на практике довольно просто. Я бы не сказал, что подход громоздкий, хотя, конечно, при такой структуре файлов папок может оказаться многовато.
Gravity UI (Яндекс)
В Gravity UI от Яндекса цветовая система тоже строится «от объекта».
Из любопытных моментов можно отметить, что все примитивы цвета здесь располагаются в одной вкладке и имеют градации от 50 до 1000, при этом в той же категории объединяют как цветовую растяжку, так и варианты с разным уровнем прозрачности.
Здесь всё структурировано практически идеально — видно, что над системой работали настоящие перфекционисты. В других дизайн-системах я не встречал такой аккуратной работы с токенами.
Момент: нет отдельной переменной для иконок, вместо неё используют переменную текста. Ещё одна деталь — цвета в стилях ссылаются на эти же цветовые переменные. Похоже, что стили остались от более старой версии, и теперь это выглядит как некий «рудимент». Я уточнял в чате дизайн-систем, почему так, но мне не смогли подсказать какую-то иную причину.
Paradigm (VK)
В Paradigm, как и в Gravity UI, цветовое построение ведётся «от объекта». При этом здесь нет отдельного уровня примитивов.
В итоге удалось создать систему, которая остаётся достаточно компактной: всего 139 цветовых токенов (в сравнении с 382 у Carbon). Для контраста, в Gravity UI насчитывается 128 семантических токенов, но зато — 1089 примитивов.
Ant Design
(Рассмотрим Ant 5.16, его нет в открытом доступе)
В Ant Design отсутствуют конкретные примеры использования компонентов (на сайте они представлены лишь в общем виде). Построение цвета здесь реализовано «от объекта»
Однако, в отличие от Carbon, Gravity UI и Paradigm, состояния вынесены в отдельные категории. Например, цвет для текста ошибки можно найти в папке Error, где также располагаются токены типа ErrorBg, ErrorBorder и другие.
В других дизайн-системах цвет текста для ошибок обычно располагается в папке Text.
Также в Ant Design для каждого компонента предусмотрены свои токены. Например, главная кнопка имеет токен Button/Global/Primary, который ссылается на семантический токен Colors/Brand/Primary/colorPrimary. Однако эта связь видна только в меню Local Variables. Такой подход распространяется на все компоненты.
Всего примитивов и семантических токенов — 217, а компонентных токенов — 1801. Если вам известны преимущества такого разделения, напишите комментарий.
Бонусное Яблоко
У Apple есть официальный UI Kit для iOS и iPadOS 18. В нём, например, для кнопок задан цвет текста с обозначением Color/Blue.
Вы, наверняка, читали множество статей о том, что цвета следует именовать по их семантическому назначению, а не по характеристике. Однако Apple не перекрашивает свои переменные для разных задач — хотя, по идее, это было бы логично: в подкастах ведь фиолетовый акцент, а в фитнесе — зелёный. Возможно, нам не показывают все нюансы, а может, в Apple работают настоящие гении, способные создать красоту даже с ограниченным набором цветов. Кроме того, у них есть категория Miscellaneous для тех цветов, которые не укладываются в привычную логику.
Объективные выводы
Формат построения:
Большинство просмотренных систем (Carbon, Gravity UI, Paradigm, Ant) построены от объекта — то есть цвета задаются исходя из принадлежности к определённому элементу.
Состояния взаимодействия:
Чаще всего состояния, такие как Hover или Selected, располагаются рядом с обычным (базовым) состоянием. Такой подход характерен для IBM, Fluent 2, Gravity UI и Ant.
Примитивы:
Наверное, самый простой и понятный вариант — использование базовых цветовых растяжек.
В Ant Design они заданы от 1 до 10, в IBM — от 10 до 100;
В Fluent 2 диапазон выглядит как «-50 – Primary – +60»;
В Gravity UI — от 100 до 1000 с дополнительными вариантами Alpha.
Субьективные выводы
Формат построения:
Мой выбор Fluent 2 — разделение на Background и Foreground, а также система по z-index кажется действительно удобной. Material, тоже хорош, но для новичков его подход может показаться менее понятным.
Состояния взаимодействия:
В Material 3 мне понравилась идея с отдельным слоем состояния, где накладывается цвет с небольшой непрозрачностью. Это простой и понятный метод, который способен значительно сократить количество вариантов.
Примитивы:
Из всех вариантов мне особенно близок подход Fluent. Он самый понятный. Если речь идёт о оттенках серого. Тут тоже Fluent 2: каждые два значения яркости (HSB) задают новый токен, все токены не пригодятся, но гарантирует минимальный уровень контраста между слоями (а Ant я не понял до конца).
Дополнительная категория:
Конечно, приятно, когда все токены укладываются в единую логику, но это не всегда самый удобный вариант. Категория Miscellaneous (Разное) заслуживает внимания — и Apple, и IBM используют её, а кто я такой, чтобы спорить с ними?
Спасибо за прочтение
Надеюсь, статья была полезной. Делайте свои выводы — я уже поделился своими. Заглядывайте в мой тг — там я стараюсь делиться пользой чаще.