New

Try out the Ether System React starter kit!

View on Github

Github

See how we structured and built this site using Ether to power all of its styling.

CodePen

Browse source code, generators, and examples of how Ether's libraries work.

Medium

Read the rationale behind the libraries along with other design system lessons.

About

Visit The Scenery

Meet the team behind Ether and see what else we work on during the day.

Contact

Get In Touch

If you need help implementing Ether on your own project or product, just holler.

Spacing

Intro to Spacing

Generating the size of the spacers for websites used to be an arbitrary task based on a defined base—10 or 12 usually. This fails to account for the size of the fonts used in the system, which ultimately ends up ignoring the thing most commonly associated with spacing: typography.

We solved this problem of tying the spacing to the font system by defining cap as the cap-height of the font family at the base-zero size. This value is then applied to a Fibonacci-style sequence to generate a series of mathematically-derived spacer sizes that align to the core sizing of the typeface being used.

When two fonts are being used, it's best to define cap using the body copy instead of any heading or display fonts.

Core Principles

Don’t want to read the article? Here’s the long and short of it.

  1. Define spacing based on type, not fingers (base-10)
  2. If it's not that different of a space, don't make it
  3. Spacing should be based on something flexible not arbitrary

Code

The entirety of the Spacing system exists in one file: in this case spacing.scss It holds the cap size and spacer definitions, as well as all the necessary mixins and helpers to implement this system throughout the front-end code.

Below is a simple example of defining these core variables and mapping them to sizes.

We highly recommend using a CSS pre-processor such as Sass to work with variables. If CSS Variable support is desired, you will need to add a PostCSS script to your build system in order to use this feature in all browsers.

For CSS Variable support, we recommend post-css-variables. The example code will be in Sass.

_spacing.scss

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 -----------------
 Sample Typography-based Spacing System
 -----------------
**/

// Cap-height of the base-0 font size
$cap: .9ex;

$spacer-none: 0;
$spacer-2xs: round($cap * .5);
$spacer-xs: $cap;
$spacer-sm: round($cap * 1.5);
$spacer-md: round($cap * 2.5);
$spacer-lg: round($cap * 4);
$spacer-xl: round($cap * 6.5);
$spacer-2xl: round($cap * 10.5);

Spacer Values

Each Spacer employs a Fibonacci-style sequence starting with 0 and 0.5 as initial values. Along with a $cap based off the body copy font cap height, our sequence builds.

Due to the nature of the Fibonacci sequence, our spacing sizes drift naturally upwards resulting an a clean and purposeful set of Spacer values.

Spacer Value
$spacer-none 0
$spacer-2xs 5px
$spacer-xs 9px
$spacer-sm 14px
$spacer-md 23px
$spacer-lg 36px
$spacer-xl 59px
$spacer-2xl 95px

Spacing Mixins

From here, mixins can be utilized to generate padding and margin values for use throughout the design system. These mixins generate both classnames for usage within markup, as well as helper functions for internal spacing.

Here is an example of a classname mixin and an internal spacer function mixin.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Create a map of Sizes
$sizes: (
  none: $spacer-none,
  2xs: $spacer-2xs,
  xs: $spacer-xs,
  sm: $spacer-sm,
  md: $spacer-md,
  lg: $spacer-lg,
  xl: $spacer-xl,
  2xl: $spacer-2xl
);

// optional design decision to reduce mobile spacing by 30%
$mobile-modifier: .7;

// Margin CSS Classes
// Usage: class="m-t-spacer-xs"
@each $size, $value in $sizes {
  .m-t-spacer-#{$size} {
    margin-top: $value * $mobile-modifier;

    // breakpoint() comes from "mixins.scss"
    @include breakpoint(sm) {
      margin-top: $value;
    }
  }
}

// Margin Internal Spacing Mixins
// Usage: @include m-t-spacer-($spacer-md);
@mixin m-t-spacer-($value) {
  margin-top: $value * $mobile-modifier;
  @include breakpoint(sm) {
    margin-top: $value;
  }
}

Implementation

The Ether Spacing System is simple to set up, simple to use, and looks natural in any layout. The above generated mixins can be used as classes for external spacing...

1
<div class="m-t-spacer-xs">...</div>

...or as an @include for internal spacing.

1
2
3
4
5
6
.card {
  &.heading {
    @include m-t-spacer-($spacer-md);
    color: $type--dark;
  }
}