Bringing the power of styles preprocessing to Sketch

Design tokens is a concept brought to help manage the complexity of modern design systems. It’s a set of ground level rules to follow both for designers and developers. But there’s a problem the designers have that is not addressed by the modern design tools.

Alexey Kalenyuk
Design + Sketch

--

The problem is that with the growing number of base styles and their variations you as a design can easily end up with hundreds of those. That’s insane and there’s nothing around in modern design tools today to help designers manage such complexity.

The problem is not the brand new and we’ve seen it before in CSS world. We have also seen how it has been successfully solved with the help of CSS preprocessors. As designers and developers deal with the same matters while defining the visual layer of the product, the style preprocessing apptoach might also work for both.

Meet Puzzle Tokens plugin for Sketch.

Puzzle Tokens allows you to apply styles directly to both Sketch files using Less syntax and its built-in functions to generate and manipulate colors, gradients, sizes and so much more.

Puzzle Tokens plugin helps you use the power of Less to define styles and apply it to Sketch styles, symbols and artboards

You can read more on which parameters are supported on the plugin’s Git page and here let me share some examples of how it works.

Update: Starting from version 5.x Puzzle Tokens support Sass as well. Visit another article to learn how Sass works with Puzzle Tokens or go down for Less examples.

The most basic thing you can do with Puzzle Tokens is create a Sketch style and assign a property to it using Less/CSS syntax. Let’s do it.

We’re going to create a shared style named “Backgrounds/Brand” with a background color value equal to #db0482. Here’s how to do that using CSS syntax:

Now if you run the Puzzle Tokens plugin (please refer to How to Install section first), it would ask you to provide a Less file with styles that should be used to generate Sketch styles. If you feed it the file above you’ll get the following appear in Sketch shared styles palette:

As simple as that. But would all the fuss worth it if limited with such basic abilities? Definitely not. Luckily, with Less+Sketch integration we got so much more power than that. Let’s dive deeper to see some of the greatest features of Less that we as designers can have to their disposal.

Example 1. Defining a base palette

Let’s define a base color palette that we’re going to use and build upon in the future:

It’s an array of semantic keys and values that might be aligned with your product brand guidelines.

Now we need to propagate those values to Sketch. This is also done using basic CSS syntax:

Classes and elements of CSS notation are interpreted as pages, groups and layers in Sketch. After applying the rules to a Sketch file Shared styles are being created:

Shared styles in Sketch are created automatically

Let’s assign styles to layers and see how it looks like:

We’ve just programmatically defined a base color palette and propagated it into Sketch Shared Styles.

This kind of style definition in code still feels like lots of manual labor with much space for human errors which we would like to avoid by any means. And here is where Less shines. Let’s rewrite the palette definition using Less loops:

Defining a palette using Less loops.

After applying Less style definitions to Sketch file via Puzzle Tokens plugin once again we’re getting the same results but with twice as less code. Less is more!

Example 2. Generating neutral shades palette

Besides base colors that is a core of a brand identity of the product, we also need a subset of shades which can be used for utility purposes of building the UI: shadows, borders, subtle backgrounds etc.

It’s easy if you leverage the power of Less. Let’s take a look. We have several requirements to a sub-set of shades:

  • We want to create a sub-set of Neutral styles within the Backgrounds group
  • Also we want those shades to not be plain black derivatives but be built based on the brand black (which is not pure black, remember?) to keep visual consistency with the brand.
  • From the whole spectre of shades from black to white we only want to use the lighter part: we don’t intend to use darker shades at all.
  • We’d like to have not too many of those. Let’s say we want 7 shades to deal with.

A simple expression below does it all for us:

  • Hierarchy of styles is done by nesting of .Neutrals inside .Backgrounds which will be transformed into Backgrounds/Neutrals styles hierarchy in Sketch
  • each(range(7) {...}) part creates a loop which runs 7 times, creating 7 slots for shades for us.
  • .Neutral-@{index} creates a unique name for each shade in Sketch (Neutral-1, Neutral-2 etc)
  • tint() function generates brighter versions of a brand black color
  • As we didn’t want the whole range of shades, with the formula inside tint() we shortened the color range to a half and moved the starting point of a range to approximately the middle of a range. 50% addition would allow us to start generation precisely from middle. But in this case we would get a pure white as the last generated shade. That’s why we replace 50% with 45%, which means that the brightest shade will have 95% of lightness component of the brand black in HSL color space. This is perfect for subtle backgrounds.

As a result we got this:

The Shared Styles palette has been also automatically extended to have a sub set of netrual backgrounds:

Now if we wanted to update base colors for some reason (rebranding, color refinement, you name it), all the derivatives would automatically be rebuilt and propagated to theSketch Shared Styles via Puzzle Tokens plugin.

Let’s update the brand black color in our color subsystem to be more green-ish and see how it affects all the shades which are built based on the brand black:

Updating a single color yields the automatic update of all the dependent styles:

Before:

After:

The Styles palette in Sketch has also been automatically updated:

This is what makes a “system” out of a design.

Now when all the background styles are in place, let’s take care of the text styles.

Example 3. Taking care of the text styles

Sketch treats text styles as a separate type of styles. Which might look unnatural for those have used to a CSS approach where every element may have full set of properties defined, no matter if it is a border, a background or a text you want to apply a style to.

But it is what it is and we’re going to do the same for the text styles so we have the full set of styles defined to our disposal. Dealing with text styles is a bit more complicated in Sketch as you have to create a style per every eligible mutation. So for every font size, color and alignment option there should be a style created: it could be dozens of permutations which is hard to create and maintain with bare hands.

  • We want font sizes to be defined for H1, H2, H3, H4 headings, normal texts, small texts and tiny texts
  • We want to have the same font color set as we have defined by brand.
  • And we want to have all those in 3 modes of alignment: left, center and right
  • To address all the requirements we would need 7*9*3=189 text styles created! Just to not be overwhelmed by the amount we’d like it to be nicely and meaningfully grouped in the Shared Styles palette.

How Less and Puzzle Tokens can help us in this indeavor? Easily. We’re going to utilize nested loops to create all of it automatically.

First, we need to define a range of options for font sizes and alignment options which we want to be available in the Shared Library. it’s easy to do via arrays, same was as we did it before with brand colors:

The only thing which is left to do is generating a bunch of nicely grouped styles for every permutation:

As you can see we’re using loops to go through values in @colors , @font-size and @text-align arrays to programmatically generate styles with the names based on the keys and values of corresponding properties.

Heads up! You don’t need to explicitly state which type of Sketch style to create: layer or text. Puzzle Tokens detects which properties are used and if the property is related to text styles (like, font-size, text-align etc), it automatically creates a text style based on that. Otherwise it will create a regular layer style.

Let’s see how it looks like in Sketch after applying Less styles via Puzzle Tokens:

And, with the styles applied to the layers:

Example 4. Building accessible color combinations

To make sure the background and text color pairs are playing good together in terms of accessibility and contrast we’re going to use a built-in Less function to generate a color which is contrast to another color based on WCAG recommendations.

For every background color style we want to have a suitable text color. And we want to have it as a subset of text styles. We’re going to call the subset ContrastTo , meaning that we’re selecting a text color contrast to one of the background colors. To do that we’re going to extend out text style definition with one extra loop:

Lines 20 to 28 generate text styles contrast to a set of base colors. Lines 30 to 38 do the same for neutral shades. Let’s check how it worked out in Sketch:

As you can see text style color is automatically set to be contrast to a specific background color. You can go fancy by replacing pure black and white text colors with something more appropriate for the brand: check docs for the contrast function in Less.

How to install

Now when you got familiar with the approach and the capabilities of Puzzle Tokens plugin, why not try it yourself? In order to get it running you need a NodeJS istalled.

  1. Download and install Puzzle Tokens plugin
  2. Download and install Node.js
  3. Instal less module using the following commands in Terminal:
sudo -s  
npm i less -g

4. Use examples provided to jumpstart or create your own from scratch following the examples above.

Naming conventions

To address styles and layer properties in Sketch the following convention is used.

Addressing styles

Sketch style named “Backgrounds/Primary” can be addressed in various ways:

Option 1

.Backgrounds .Primary { ... }

Option 2

.Backgrounds {
.Primary {
...
}
}

Symbols can be addressed using hash (#) sign at the beginning of the the symbol name. If you have a symbol called Button with a layer called Back inside, you can address this layer the following way:

Option 1

#Button .Back {
...
}

Option 2

#Button {
.Back {
...
}
}

Addressing names with a slash (/) inside.

Sketch can build a nice hierarchy in the symbols or styles pallette by treating slashes (/) in a special way. So the name “Backgrounds / Primary” gets renders as a menu item names “Backgrounds” with a sub-menu having “Primary” item in it. we wouldn’t want to lose this conviniece. Here is how to address it in Less file.

Styles

.Backgrounds .Primary {...} will address or generate a style called Backgrounds/Primary.

Symbols and Artboards

#Button #Primary .Back {...} will address a layer named Back inside a symbol named Button/Primary .

Addressing names with blank spaces inside.

Original CSS/Less notation only supports single-worded addressing and you cannot use spaces in the address path. It’s not always usable to see names in Sketch Styles pallette like DarkBackground without a blank as natural delimiter between words. With Puzzle Tokens there’s a way to have the naming the way you want. Here’s how to do it:

If you have a Dark Backgrounds name, you address it like this:

.Dark__Backgrounds { ... }

The double underscore is replaced with a single space after the Less file is applied to Sketch.

Properties supported by Puzzle Tokens

Here’s a quick recap of properties that are supported by the plugin.

For layer styles:

  • background-color (plain colors and linear gradients are supported)
  • box-shadow (regular and inset)
  • border-radius
  • border-width
  • border-color

For text styles:

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

What’s just happened

We’ve defined the visual layer in an explicit, self-documented fashion using Less syntax and then applied it to Sketch styles via Puzzle Tokens plugin. By following this approach we also avoided a load of handwork to create hundreds of styles.

As a result we got an extendable and maintainable library of design tokens and rules to apply them which define the visual layer of our design system and is ready to be used both by designers and developers.

Now it’s about time to try it out!

Useful links

--

--

Alexey Kalenyuk
Design + Sketch

Head of UX at CloudBlue, Ingram Micro Cloud, Co-founder at Startex.io