Как не свихнуться, работая со визуальным слоем дизайн-системы в Sketch

Alexey Kalenyuk
11 min readOct 24, 2019

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

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

Мы столкнулись с этой проблемой, когда стали систематизировать визуальный язык продуктовой линейки Ingram Micro Cloud. Например, одних только цветов — базовых и производных от них — у нас 60. Если учесть другие аспекты визуального слоя — типовые размеры, радиусы скруглений, толщины итп — выйдет несколько сотен позиций. Наличие контрастной темы в продукте увеличит этот объем вдвое.

Стоит отметить, что большая часть этого списка — это комбинации неких базовых значений или производные от них. Часть из этого связана четкими закономерностями, буквально математическими. При попытке получить это разнообразие в виде набора стилей для Sketch мы получили классический “комбинаторный взрыв”: чтобы поддержать стилевую вариативность на таком уровне мы были бы вынуждены вручную создать пару сотен стилей в Sketch.

А что там у девелоперов?

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

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

С ростом сложности веб-сайтов и приложений описывать внешний вид на чистом CSS стало затратно по многим причинам. В далеком 2006 году на свет появился, кажется, первый CSS-процессор — SASS. Следом, спустя 3 года — Less. По сути своей препроцессор — это надстройка над CSS, которая позволяет писать в разы меньше кода, получая на выходе не менее полное описание стилей, чем это можно было бы достичь на чистом CSS.

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

Дизайнеры же до недавнего времени вынуждены были работать с ручным инструментом, не имея возможности по сути алгоритмизировать и упрощать себе работу, избавляться от рутины.

Puzzle Tokens

Когда мы решали задачу управления стилевым комбинаторным взрывом, то поняли, что для нашей задачи, связанной с генерацией и управлением сотнями стилей, подход, предложенный CSS-препроцессорами отлично бы подошел. Поэтому мы сделали плагин, который позволяет применять инструкции языка Less к файлам и стилям Sketch.

Итак, знакомьтесь: Puzzle Tokens. Плагин для Sketch, который позволяет описывать и автоматически генерировать стили в Sketch. С помощью него можно легко описать в Less все нужные нам параметры:(цвета, градиенты, тени, скругления, размеры итп), рассчитать недостающие и применить это все к стилям, символам или отдельным артбордам в .sketch файле.

Puzzle Tokens для Sketch

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

Самое простое, что можно сделать при помощи плагина — это создать стиль в Sketch и назначить ему какой-нибудь цвет.

Допустим, я хочу создать стиль с названием “Backgrounds/Brand” и сделать, чтобы цвет заливки у него был #db0482. Вот как это делается:

Запускаем плагин, говорим ему, из какого файла применить стили, и получаем новый стиль в палитре Sketch, созданный на основе правил, описанных в Less-файле:

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

Пример 1. Создание базовой палитры цветов.

Определим базовые цвета, данные нам свыше (например, брендбуком):

По сути это просто массив названий цветов и их значений.

Теперь мы хотим сделать в Sketch соответствующие слои на основе этих цветов. Вот как это делается:

Селекторы классов и элементов из CSS-нотации интерпретируются как путь до слоя в Sketch. Если применить эти определения при помощи плагина к .sketch-файлу, то станет понятно, как эта нотация переносится в Sketch:

Стили в Sketch создаются автоматически, если не найдено уже имеющихся с таким же названием

Применим созданные стили к слоям и посмотрим, как это выглядит:

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

Создание базовой палитры цветов, используя массивы и циклы Less

Применив это к .sketch-файлу мы получим тот же результат, и это потребует в 2 раза меньше писанины.

Пример 2. 50 оттенков серого (и любого другого)

Помимо палитры основных цветов, которая отражает лицо продукта, его бренд и может быть дана нам свыше (например, отделом маркетинга), дизайнерам, как правило, необходимо гораздо больше цветов для работы. Это всевозможные оттенки и градации, которые можно использовать для раскраски рамок, фонов, теней.

Один из способов получить набор цветовых производных, которые при этом останутся когерентны основному цвету, то есть будут сооветствовать бренду — это изменение значений параметра светлоты (Lightness) в цветовом пространстве HSL.

И вот, допустим, что мы захотели таки получить себе набор оттенков основного цвета, чтобы использовать их для цвета рамок или цвета заливок. В этой задаче Less может нам неплохо помочь. Сперва сформулируем свои хотелки:

  • Хотелось бы, чтобы это были не оттенки чистого серого, а оттенки, построенные на основе одного из наших брендовых цветов (наш корпоративный черный), чтобы сохранить визуальную консистеность с брендом
  • Из всего спектра возможных оттенков между черным и белым нам понадобится только светлая часть, мы не собираемся использовать темные оттенки.
  • Оттенков нам нужно немного, штук 7 подойдет
  • И последнее — эта палитра должна называться Neutrals и быть подмножеством основной палитры (мы сделали ее в прошлом примере, она называлась Backgrounds)

Все эти требования удовлетворяются вот таким образом:

Сейчас разберем по порядку.

  • Иерархию вложенности новых стилей в Sketch мы задаем, используя так называемый прием “наследования” из Less: мы как бы вложили .Neutrals внутрь .Backgrounds . В результате в Sketch мы в палитре стилей увидим, что папка с новыми стилями называется Neutrals и вложена внутрь папки Backgrounds.
  • each(range(7) {...}) проходит по циклу 7 раз и по сути готовит нам 7 слотов для новых стилей.
  • .Neutral-@{index} именует каждый из стилей, используя .Neutral в качестве общего префикса и его порядковый номер. В Sketch это названия будут выглядеть как Neutral-1, Neutral-2 и так далее
  • функция tint()c создает для нас более светлые оттенки корпоративного черного
  • Так как мы хотели получить всего 7 оттенков из светлой части диапазона, мы как бы начинаем их генерацию с середины этого диапазона. Кроме того, если не предпринять мер, то крайний, самый светлый из оттенков при применении функции tint() окажется равен чистому белому. Чистый белый нам не нужен (он уже у нас есть в основной палитре), поэтому, чтобы все было как хотим, мы сдвигаем начало расчета диапазона не ровно на середину, а чуть левее (ставим сдвиг в формуле не 50%, а 45%, например) и, таким образом, получаем 7 оттенков светлой части диапазона без чистого белого в конце.

В результате получаем:

А в палитре стилей Sketch теперь есть подпапка Neutrals:

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

Давайте же его поменяем на более зеленый и посмотрим, что случится:

закоментировали старый цвет, вставили новый цвет

Благодаря возможностям Less изменение основного цвета повлечет автоматический пересчет и изменение всех его производных.

До (старый черный):

После (новый черный):

Стили в Sketch тоже автоматически обновились:

Мы разобрались со стилями слоев, теперь перейдем к текстовым стилям.

Пример 3. Создаем текстовые стили

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

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

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

Итак, мы бы хотели:

  • чтобы у нас были созданы стили для типовых размеров шрифта (Заголовки H1-H4, обычный текст, текст поменьше, и самый мелкий шрифт, на всякий случай)
  • чтобы для всех наших размеров мы могли бы перекрашивать в наши брендовые цвета, которые мы задали выше.
  • чтобы нам были доступны три вида выравнивания, по левому и правому краям и по центру
  • чтобы стили были бы сгруппированы по смыслу в палитре Sketch.

Если посчитать количество стилей, которые нам нужно создать, чтобы удовлетворить эти достаточно базовые требования, то получится 7*9*3=189 текстовых стилей. Сто восемьдесят девять, Карл.

Как тут может нам помочь Less и Puzzle Tokens? Помощь придет в виде наследований, циклов и параметризации. Сейчас мы все сделаем.

Сперва опишем все исходные данные внутри Less. Зададим (удобнее в виде отдельных массивов) все нужные нам размеры шрифтов и виды выравниваний:

После этого нам лишь останется пробежаться по ним всем циклами и создать нужные стили для каждой нужной вариации:

Тут мы проходимся по трем наборам значений (цвета @colors, размеры шрифта @font-size и выравнивания @text-align) и автоматически генерируем пачку соответствующих стилей.

Запускаем плагин и смотрим, что получилось:

Все 189 стилей создались и сгруппировались по смысловым кучкам.

И, если применить получившиеся стили к слоям в Sketch, то получим следующее:

Пример 4. Готовим контрастные цветовые пары

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

Для быстрого подбора контрастных цветовых пар можно использовать одну из встроенных в Less функций. Функция contrast()отдает цвет, контрастный искомому, основываясь на рекомендациях и формулах, предложенных WCAG.

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

Чтобы получить набор текстовых стилей, контрастных заданному цвету, нужно всего лишь пройтись по набору цветов, которые мы определили ранее для заливки (@colors), и получить для них рассчитанное контрастное значение. Для этого мы просто немного расширим то, что ранее написали для генерации текстовых стилей:

Строки с 20 по 28 создают текстовые стили с цветом, контрастным к основноым фоновым цветам.

Строки с 30 по 38 делают тоже самое, но для палитры нейтральных оттенков.

Посмотрим, что вышло:

Каждая надпись, размещенная на подложке, имеет контрастный к ней цвет. По умолчанию, выбор делается между белым и черным цветами, но Less позволяет сделать этот выбор более разнообразным, смотрите доки по функции contrast.

Установка

Теперь, когда мы прошлись по основным возможностям, которые дает Puzzle Tokens, расскажу как установить плагин.

  1. Скачайте Puzzle Tokens последней версии и установите его в Sketch
  2. Скачайте и установите Node.js
  3. Устновите Node-модуль less используя следующие команды в консоли MacOS:
sudo -s  
npm i less -g

Далее проще всего будет скачать файлы с примерами из статьи и поиграться с ними.

Условности, на которые мы пошли, чтобы все заработало

Плагин относится к Sketch-документу как к дереву элементов, состоящему из страниц, артбордов, слоев и стилей, по аналогии с деревом элементов веб-страницы (DOM). Поэтому концепция CSS-селекторов отлично подошла, мы лишь ввели некие условности, чтобы адаптировать ее к реалиям Sketch.

Адресация стилей документа

К стилю с названием “Backgrounds/Primary” можно обратиться несколькими способами::

Способ 1

Backgrounds Primary { ... }

Способ 2

.Backgrounds .Primary { ... }

Способ 3

Backgrounds {
Primary {
...
}
}

Адресация символов и артбордов

К свойствам слоев символа можно обращаться аналогичным образом с одним условием: первый селектор, обозначающий имя символа, должен начинаться с решетки (#).

Например, если у нас в документе есть символ по имени Button, а в нем есть слой по имени Back, то чтобы добраться до свойств слоя, можно использовать следующие способы:

Способ 1

#Button Back {
...
}

Способ 2

#Button {
Back {
...
}
}

Как обращаться к стилям со слешом (/) в названии

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

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

Для стилей документа:

.Backgrounds .Primary {...} создаст стиль с названием Backgrounds/Primary. Если стиль уже создан, то просто применит к нему нужные свойства.

Для символов и артбордов:

#Button #Primary Back {...} доберется до слоя с именем Back, который находится внутри символа с названием Button/Primary .

Что делать, если хочется пробелы в названиях стилей/символов

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

Например, если нам надо создать стиль с названием Dark Backgrounds , то мы запишем это таким образом, заменив пробел двойным знаком подчеркивания:

Dark__Backgrounds { ... }

Двойной знак подчеркивания будет интерпретироваться плагином как одиночный пробел, и после применения less-файла в Sketch вы увидите стиль с названием “Dark Backgrounds”.

Свойства, поддерживаемые плагином

Вот какие свойства плагин уже поддерживает.

Для стилей слоев:

  • background-color (поддерживаются обычные цвета во всех доступных в Less форматах и линейные градиенты)
  • box-shadow (внешние и внутренние)
  • border-radius
  • border-width
  • border-color

Для текстовых стилей:

  • color
  • font-size
  • font-family
  • font-weight
  • line-height
  • text-align
  • text-trasnform
  • vertical-align

Итого

Puzzle Tokens позволяет описывать визуальный стиль в формате Less/CSS. Это экономит массу времени, помогает создать “систему из дизайна”, такое описание легко поддерживать и обновлять из-за его компактности, модульности, эксплицитности описания. Кроме того, все это находится в одном месте — Less-файле. Стоит ли говорить, что очередной ребрендинг уже не застанет вас врасплох?

Плагин бесплатный и с открытым кодом.

Полезные ссылки

--

--