Image for post
Image for post

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.

Alex kalenyuk
Oct 24, 2019 · 10 min read

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.

Image for post
Image for post
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:

Image for post
Image for post

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

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:

Image for post
Image for post
Shared styles in Sketch are created automatically

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

Image for post
Image for post

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

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:

Image for post
Image for post

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

Image for post
Image for post

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:

Image for post
Image for post

After:

Image for post
Image for post

The Styles palette in Sketch has also been automatically updated:

Image for post
Image for post

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

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:

Image for post
Image for post

And, with the styles applied to the layers:

Image for post
Image for post

Example 4. Building accessible color combinations

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:

Image for post
Image for post

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

  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

Addressing styles

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.

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

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

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

Design + Sketch

The best collection of articles, tips, tutorials, and…

Alex kalenyuk

Written by

Head of UX at Ingram Micro Cloud, CloudBlue

Design + Sketch

The best collection of articles, tips, tutorials, and stories on designing and prototyping with Sketch and beyond

Alex kalenyuk

Written by

Head of UX at Ingram Micro Cloud, CloudBlue

Design + Sketch

The best collection of articles, tips, tutorials, and stories on designing and prototyping with Sketch and beyond

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store