How to construct a design system

Tips for designing and building a consistent design system.

Colm Tuite
Feb 22, 2017 · 10 min read

Without doubt, I get asked about design systems more than anything else. So, having spent the majority of the past few years thinking about how to design, build and present design systems for products like Marvel, Bantam and Modulz, I figured I’d share some of what I’ve learned along the way.

What is a design system?

A design system (as it pertains to tech products) is more than a framework, UI toolkit or component library. It’s more than a style guide or set of code guidelines. It’s even more than the sum of those parts. A design system is an evolving ruleset governing the composition of a product.

There are many facets to any good design system — starting with company culture/mission and trickling all the way down to branding, copywriting, component libraries and other design language. The higher level points are arguably the most important aspects of any design system but for the purposes of this article, I’m going to assume that as a company — you know who you are, what your mission is and how your products should look, feel and function.

Once you have those critical factors in place, you can convert that knowledge into a cohesive design language.

Designing a style palette

Even the simplest heading component is a collection of multiple reusable styles…

We need to break things down until we reach the irreducible minimum; the most essential styles. A good place to start is the full list of CSS style properties. Most of these properties only accept fixed values and therefore can be reused on every website on the internet. The properties which accept custom values are ultimately what will differentiate our product from other products. These custom values are what will define our global style palette. Our global style palette is what we will use to design and build every single aspect of all of our products.

When we’re finished, not a single style should exist in our product that has not been predefined in our global style palette.

Colour

For our primary brand colour, let’s choose blue. For our secondary brand colour, let’s go with its complementary counterpart: orange.

Brand colours

Utilising colour to communicate success and failure is a common design pattern, so let’s add green and red to our colour palette for that purpose. Colours like black and yellow might work well too.

Success and failure colours

Lastly, we need some grey colours. Most UIs will need at least the following grey colours:

  • A very light grey for backgrounds
  • A slightly darker grey for borders, lines, strokes or dividers.
  • A medium grey for subheadings and supporting body copy.
  • A dark grey for main headings, body copy and backgrounds.

Of course, you may need more greys. You might need three different shades for body copy. You might prefer two different stroke shades. That’s up to you. The point here is that you predefine whatever styles you need upfront so they are reusable throughout your entire product at a later stage.

As a final touch, we may also want to add tint or shade variations for each of our colours. These can be useful when it comes to designing components for adding light backgrounds or dark strokes.

Our final colour palette

Shadows

Let’s take a step back and consider what we’re trying to achieve with our shadows. We’re obviously trying to add some perspective to the UI but it’s likely that many components can benefit from the same effect. So let’s abstract the styles away from the individual components and into our global style palette.

These four shadows should be enough to style every component in our system:

  • A subtle shadow to raise interactive components and add affordance.
  • A more pronounced shadow for a hover effect on components.
  • A strong shadow to give perspective to dropdowns/popovers and other similar components.
  • A distant shadow for modal components.
Our range of shadows from subtle to distant.

Type scale

Just like with notes in a piece of music, our type should adhere to a scale. This helps to sustain a smooth vertical rhythm. This can sound a bit daunting at first, but luckily, some very smart people have already figured it all out for us over the years. Tim Brown has built a great website to display various type scales. Adam Morse has open-sourced his implementation of the diatonic type scale. I generally find the “Major Third” scale works well for most web products.

The next step is to decide roughly which font sizes we will need, then plot them on our “Major Third” type scale.

  • Default (1em) for standard text that will appear in many places throughout our marketing site, UI etc. 16px is the default browser font size so let’s run with that.
  • A slightly larger size for large body copy in a blog for example.
  • A couple of larger sizes for headings and sub-headings.
  • A very large size for section titles.
  • A ridiculously large size maybe for prices on a pricing page for example.
  • We will also need some smaller sizes for smaller body copy, input hints and other secondary text.
Type scale

Border radii

  • Small border radius for tiny components like checkboxes, tags and labels.
  • Medium border radius for buttons and inputs and similar components.
  • Large border radius for cards, modals and other large components.
2px, 4px and 8px border radii

Note: We will also need a 50% border radius for building circular components like avatars etc.

Spacing scale

Like with type, by adhering to a spacing scale, we can ensure that each of our components and layouts will be uniform. My favourite go-to spacing scale is Material design’s 8dp grid. Elliot Dahl has written a great article about the 8pt grid system and its benefits.

Sticking to 8dp increments, we can plot out a number of spacing values that we can use to design every single component and layout in our suite of products.

We can also use these spacing values to define a set of widths, heights and line-heights that we can reuse for sizing buttons, form inputs, avatars and other similar components. Since these components often appear alongside each other throughout web products, it helps if they follow the same sizing scale to avoid any unwanted discrepancies.

Letter spacing

3 or 4 letter spacing values should do the trick.

Building a component library

At this stage, we shouldn’t need a single style that hasn’t already been defined in our style palette. The creative process happened during the style palette design phase. From this point on, whether it’s a colour, font size, margin/padding value, width/height or otherwise, every style we use to design our components and layouts should be plucked from our style palette. Almost nothing new should need to be introduced. That might sound extreme or unreasonable, but on the contrary, this is where I think a lot of people go astray.

Dave Rupert ran this Twitter poll recently asking where to put code that overrides the styling on a button component, if that button is inside a modal component, for example.

Harry Roberts (check out this awesome work) then explained his thoughts on this in his own article. After that, Jonathan Snook expanded with his own thoughts. While I agree with the conclusions both Harry and Jonathan came to, ultimately, I think the whole debate is just unnecessary.

It’s contradictory to design a component with the intention of reusing it globally, then modify that component in just one specific part of the product. This defeats the purpose of creating a global component library in the first place. Whenever I see styles that override other styles, it’s usually either a case of hacking away at a component in order to make it fit in a tight space or tacking on a variation of a component because not enough planning went in during the earlier design stages.

Every time you override a global component in one area of a product, you also erode the consistency of your design system. When you make enough sporadic modifications to components scattered across your product, you no longer have a consistent design system. You just have a design system with an inconsistent mess hanging out the arse of it.

Let’s take a few common components and walk through how we can build them out using only the styles we have defined in our palette above.

The humble button

More components

Let’s try something a bit fancier…

This dropdown component doesn’t use a single style outside of the basic style palette we defined earlier. Using this method, we can design an entire component library, then move on to broader layouts and finally onto full screens.

Tips for the road

  • Let components do their thing. Don’t attempt to add margins to buttons, inputs, headings or other components. At the component level, you should only define the styles which appear uniform in every single instance of that component. Since margins differ on a case-by-case basis, it’s better to apply them using a wrapper div. Harry Roberts wrote an excellent article touching on this point.

I’m working on a full-blown CSS toolkit based on Bantam CSS framework that will include all the components shown in this article plus many more. The project is for Modulz, a product I’m working on but if you’re interested in using this UI toolkit yourself, let me know on Twitter. If I get enough interest, I’ll open-source it.

We’ve moved to freeCodeCamp.org/news

We’ve moved to https://freecodecamp.org/news and publish tons of tutorials each week. See you there.

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. Start a blog

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