Design System Sprint 3: Managing the Basics

A brief introduction: I’m Marcin: a former UX manager and now co-founder and CEO at UXPin — the full stack UX design platform. In this series of posts, I’m reporting on UXPin’s journey of creating our own design system.

  • In the first post, I discussed the fundamentals of design systems (the why? the what?).
  • The second post was focused on creation of the design inventory.
  • Third, we discussed in details creation of a unified color palette. Today we’re going to zoom in on the tiniest shared pieces of the user interface.

Whether we’re working on an existing product or a new product from the same “family”, we have to comply with most, if not all, of the existing UI standards. It’s a constraint we all need to accept.

UI standards bring to mind big things — color palettes, typographic scales, grids, pattern libraries. But there’s also smaller pieces that, often neglected and hardly ever documented, play a decisive role in the look and feel of our product. Think borders, radiuses, animations, space definitions (paddings, margins)… all of them crucial, all of them deserving our attention.

If you’re a designer, you probably know how annoying it is to work with undefined basics.

You need to memorize whether the basic container radius is 2px, or 3px. You need to note somewhere that a box-shadow on a floating container is represented by this verbose css declaration:

box-shadow: 0 0 60px rgba(0, 0, 0, .1);

That’s a lot to remember, so we typically either continue to inspect old designs and production code, or simply eyeball every tiny aspect of an existing interface. That means designers need to make a no-win decision between wasting time or causing design inconsistency.

Sounds like the right task for a design system!

Design Tokens

To solve the issue of undefined basic style properties, some companies (most notably Salesforce with their open source design token tool — Theo) build Design Tokens.

Design Tokens are a cross-platform, human-readable, abstraction of visual styles, that sync with all the style files in the system. Tokens are a fantastic tool. However, they’re somewhat complex, and in my experience, more suitable for companies with a mature Design Operations teams who maintain design and code consistency.

Tokens introduce a new format of storing styles data (as serialized data — either JSON, or YAML) . Although you could argue they’re more readable than CSS, they definitely look a bit scary at first.

YAML data file with border-color token from Salesforce Lightening Design System

Using Design Tokens also requires changes in the built process. If you’re using Gulp, or Webpack to build your CSS files from preprocessor files, you’ll have to first load tokens files to build variables used by CSS preprocessors. It’s not a huge task (and there’s a gulp plugin and webpack loader supporting the process), but if you’re working on getting people on board with Design System, every change can spark resistance.

Although I’m as excited about the concept of design tokens as Nathan Curtis (read his excellent post about tokens — ‘Tokens in Design System’), they require a fair amount of work and changes to our process. So, we’ve decided to solve the problem of basic style properties, with an easier and faster solution.

It’s simple:

  • Build variables and mixins for basic style properties
  • Document them in an accessible, visual way (so designers, even if they can’t code, can understand all the standards)

Thanks to this easy approach, designers and developers get a tool that tells them about standards for the most basic style properties. A tool that help create consistency between new and existing products. And it all can be done in a day.

While it’s not as automated and scalable as design tokens,it’s certainly a start. Once we get full adoption of our system, we’ll certainly revisit the concept of Design Tokens.

Setting Up the Standard

So, what should you standardize and document? It depends on the interface of your product. Ask yourself:

  • Which style properties are most pervasive and repetitive?
  • Which style properties are the hardest to recreate in code and design tools?

After asking ourselves these two questions, we decided to start with:

  • Border-radius
  • Border
  • Box-shadow
  • Transitions

You could standardize more than just border, box-shadow, and transition properties. We just prioritized what caused the most pain in the design and development process.

To set up a standard, we reviewed our interface inventory, looking for patterns associated with these three properties.

UXPin Design System Inventory

After identifying all the patterns, we listed Less variables and mixins that would let us reproduce the desired visual effect. To maintain consistency, we use naming patterns created for our color palette.

To give you an example here are our four most fundamental border mixins:

.border-base(@color: @silver-lighten-5) { 
border: 1px solid @color;
};
.border-dashed(@color: @silver-lighten-5) { 
border: 1px dashed @color;
};
.border-separator(@color: @silver-lighten-10) { 
border: 1px solid @color;
};
.border-active(@color: @blue-base) { 
border: 1px solid @color;
};

To include them in any element we just have to simple write:

.sample-class {
.border-base();
}

That dead simple tactic let us create a repository of commonly used basic style properties in just one day.

Readable Documentation for the Team

With all the variables and mixins in place, we still needed to consider how to document everything in a way that’s accessible to designers and developers.

After some deliberation, we simply created a list of standards together with examples from our inventory and descriptions in a designer-friendly format. The descriptions included the list of properties, Less variables, and CSS examples (implementation guidelines and processed less variables).

Documentation of basic style properties in UXPin Design System

Experimenting with Hovers

While working on the list of basic style properties, I started thinking about more complex patterns — mainly hover states.

Hover states usually follow a similar pattern — interactive elements might get a stronger box-shadow, lighter color, gradient or other standard property, upon hover. Setting them up on all the UI elements takes a lot of repetitive work.

As an experiment, I prepared this Less and Sass mixins that takes any given color and apply the styles used in a hover state. Here’s the Less version:

.hover(@color, @duration-base, @easing-base) {
transition: background-color @duration-base @easing-base;
text-decoration: none;
background-color: lighten(@color, 10%);
box-shadow: @shadow-base;
}

Implementation of such a hover state is quite simple:

.sample-class {
&:hover {
.hover(@blue-base);
}
}

While we haven’t implemented mixins for these generic interactive patterns, I’m really looking forward to work on them. They could save a lot of work!

The Final Word

Typically, discussions about design systems lean towards big concepts like color palettes, typography, and UI patterns. But let’s not forget that consistency also depends heavily on the silent heroes of digital design — tiny style properties.

These basic styles deserve their own place in a design system!