Front-end Architecture: Part 2 — Brand Variables

Unify your design system from the foundations up with a brand variables file.

Gav McKenzie
Author
Gav McKenzie
Published
Nov 2, 2016
Topics
How-to, Industry, Engineering

When creating CSS design systems for a website or app, it’s easy to start coding your components without thought for overall unity. Over time, this can lead to a harder to maintain code base with a disjointed feel.

We’re going to look at creating a set of core variables that can be used over and over again in order to create consistency, maintainability and faster development for the lifetime of your layout code.

TL;DR

Use this simple set of variables as the foundations for your design system.

What is a brand?

A brand is all encompassing. It’s everything from the logo, to the tone of voice, to the words used, to the colour palette.

As front-end developers, armed with CSS, we’re going to be focusing on the properties we have available in CSS for defining core layouts: typography, colours, borders, white-space and transitions.

Why have brand variables?

Brand variables increase consistency, make brand updates simpler and reduce thought during development.

By putting in the work upfront, you can reduce thought and complexity during styling, freeing up more of your energy and time for smashing out awesome layouts.

_variables.scss

Brand variables can be mostly boiled down to one of two file types. You can use your favourite CSS variable method (Native, SCSS, Less, Stylus, etc) or you can go beyond that and create a JSON file to be converted for use in CSS and JavaScript.

We’re going to be using SCSS in this example for simplicity, but this could easily be fed by a JSON file in the build process.

Naming conventions

It’s a good idea to start by defining the naming conventions for your variables. Consistent naming leads to consistent brands.

$[element]-[property]-[orientation]-[size]-[variant]

At Etch, we’re currently using hyphenated variables in the format above. Each bracketed section is optional, but this helps to reduce confusion when either naming or recalling a variable.

$input-border-top-large: .4em; // Overkill, but it’s an example
$color-brand-primary: #f66;

Palette

Getting into the variables, the colour palette is a great place to start. Every element can have colours applied to it so it makes sense to start our variables file here.

$color-brand-primary: #f66;
$color-brand-primary-light: lighten($color-brand-primary, 5%);
$color-brand-primary-dark: darken($color-brand-primary, 5%);

Colour palettes vary massively between different brands. Some may use many different colours, others are very monochromatic. Colours are also easy to get out of control and end up spiralling into hundreds of variations. By defining as much of your palette as possible at the start you can keep consistency and easily flip the colour scheme if needed.

One of our current clients recently needed to turn pink for a month for Breast Cancer Awareness month. Using our palette variables, it took just 20 minutes of development time to flip the colour scheme for the whole site and still look awesome.

Likely variations you’ll want to think about are:

  • Brand colours (primary, secondary, etc)

  • Grey tones

  • Light and dark variations

  • Communication: info, error, warning, success

  • Transparent tints like lighten or darken

  • Calls to action

Typography

Underneath all the fancy code, the internet can be distilled to words in boxes. We can style the words and the boxes. Let’s look at the words first.

There are a few core variables that span across your whole typographic system. The font family choice, line-height and basic size variants. As a bonus, I’ve also included the selection background and colour as this is often overlooked.

$font-family-cursive: cursive;
$font-family-monospace: monospace;
$font-family-sans-serif: Arial, "Helvetica Neue", "Helvetica", sans-serif;
$font-family-serif: serif;
$font-family: $font-family-sans-serif;
$line-height: 1.5;
$font-size-base: 1em; // 16px
$font-size-sm: .875em;
$font-size-lg: 1.25em;
$font-size-xs: .75em;
$selection-bg: rgba(0, 0, 0, .25);
$selection-color: inherit;

While these variables give your base typographic feel, you’ll probably want to treat the headings slightly differently. They often have a different font, a different weight, a different line-height, and the sizing in relation to the other elements can be important.

We split these out into their own section for definition and control.

$h1-font-size: 1.75em;
$h2-font-size: 1.5em;
$h3-font-size: 1.25em;
$h4-font-size: 1.125em;
$h5-font-size: 1em;
$h6-font-size: .875em;
$heading-color: $color-grey-darker;
$heading-font-family: $font-family-sans-serif;
$heading-font-weight: normal;
$heading-line-height: 1.25;

White-space

The amount of white-space on a page is a huge element of how a brand presents itself. Should it be open, calm and airy? Tight and energetic?

We use 3 different types of white-space variables: fixed, fluid and root. Each of these has variations to make it smaller or larger over a consistent amount of spacing. They also come in separate horizontal and vertical flavours for fine-grained control.

For most component level detail, you’ll likely want the fixed variables. These allow solid control when balancing UI elements that are closely grouped.

$spacing-horizontal: 1em; // 16px
$spacing-horizontal-lg: $spacing-horizontal * 2;
$spacing-horizontal-sm: $spacing-horizontal / 2;
$spacing-horizontal-xl: $spacing-horizontal * 4;
$spacing-horizontal-xs: $spacing-horizontal / 4;
$spacing-vertical: 1em; // 16px
$spacing-vertical-lg: $spacing-vertical * 2;
$spacing-vertical-sm: $spacing-vertical / 2;
$spacing-vertical-xl: $spacing-vertical * 4;
$spacing-vertical-xs: $spacing-vertical / 4;

When scaling up a page, you often need more breathing room within and around the larger UI blocks on a page. This is where our root spacing variables come in handy.

An example usage of these would be in a page hero component with a title and strapline inside. The spacing between the title and strapline would likely be a fixed size, but the spacing around them should grow as the page width increases so they don’t feel cramped on larger screen sizes.

$spacing-horizontal-root: 5vw;
$spacing-vertical-root: 5vw;

Our final set (and least used for me) is the fluid variables. These are used to make padding/spacing relative to the parent container width. They’re harder to use when needing a consistent grid layout, but do come in useful occasionally so we keep them in.

$spacing-horizontal-fluid: 10%;
$spacing-horizontal-fluid-lg: $spacing-horizontal-fluid * 1.5;
$spacing-horizontal-fluid-sm: $spacing-horizontal-fluid / 1.5;
$spacing-vertical-fluid: 10%;
$spacing-vertical-fluid-lg: $spacing-vertical-fluid * 1.5;
$spacing-vertical-fluid-sm: $spacing-vertical-fluid / 1.5;

Borders

Borders can be found on layout boxes, form inputs and in all sorts of components you might be building. Standardising the width, style and base colours make life super simple when deciding what to use.

$border-color: $color-grey-light;
$border-style: solid;
$border-width: .1em;
$border-width-sm: $border-width / 2;
$border-width-lg: $border-width * 2;
$border: $border-style $border-width $border-color;
$border-radius: 0;

Transitions

With the preceding variables, we’ve defined how the page looks, but the internet is an interactive medium. Users can click, swipe, tap, drag, hover, pinch and a multitude of other actions to interact with your content.

Defining core transitions sets how a brand feels when interacted with. Is it fast and snappy? Smooth and calm?

$transition-duration: 125ms;
$transition-timing: ease-in-out;

Element styling

So far we’ve covered abstract variables. Barring some of the heading variables, nothing has directly referenced an element to be styled. Now you have the core brand done you can move onto some element styles.

We usually like to define the base styling on form elements, links and buttons as these are some of the most important and frequently referenced parts of a UI framework.

These also help to remind you to style the different states of an element, such as :hover, :focus and :active.

Form inputs

You can see in our form input styling, we’re already re-using our core brand variables, immediately delivering consistency from the foundations upwards.

$input-bg: $color-white;
$input-bg-disabled: $color-grey-lightest;
$input-border-color: $color-white;
$input-border-color-focus: $color-grey-light;
$input-border-color-hover: lighten($color-grey-light, 5%);
$input-border-radius: $border-radius;
$input-box-shadow: none;
$input-color: $body-color;
$input-color-placeholder: $color-grey-dark;
$input-padding-horizontal: $spacing-horizontal-sm;
$input-padding-vertical: $spacing-vertical-sm;

Buttons

Buttons again make use of the core variables. You might want to include several variations here as your usage increases, such as primary, default, success, danger.

$button-bg: $color-brand-primary;
$button-color: $color-white;

Links

Last, but definitely not least, we have link styling. The web is made of interconnected, linked, content and clearly marking the paths between this content is of paramount importance. Always remember to include your interaction states for users of mice, keyboards and touch inputs.

$link-color: $color-brand-primary;
$link-active-color: darken($link-color, 5%);
$link-focus-color: darken($link-color, 5%);
$link-hover-color: lighten($link-color, 5%);
$link-decoration: underline;
$link-hover-decoration: underline;

Components and more

This covers our core variables, but you may want to go even further. You can build on your brand variables by defining component level variables that utilise your initial foundation.

By defining component level variables, you can switch out your original core variables file and power multiple brands from the same set of component files. UI framework libraries such as Bootstrap or Foundation make great use of this ability to power thousands of sites worldwide.

Summary

In this article we’ve covered how to define your brand through the clever use of a few basic variables.

From here, you should be able to hardly ever have to use actual values in your component level CSS, leading to solid, maintainable, design systems.

All code is available in the GitHub Repo