Proposal: a consistent spacing system for WordPress

Much like a type scale, a spacing system enforces consistency and simplifies decision making for UI design. This post aims to standardize one for WordPress.

What is a spacing system?

Spacing is the atomic element of an overall spatial system. A spatial system includes spacing, grid, and layout. Spacing is the foundation on which the others are built.

A spacing system is simply a set of predefined values and guidelines for how to apply them in the UI.

What benefits does it provide?

“The organization of space is key to every great design. Spatial systems, grids, and layouts provide rules that give your designs a consistent rhythm, constrain decision making, and help teams stay aligned.”

Space, Grids, and Layouts by Elliot Dahl
A diagram comparing an interface with no spacing system to one with an 8px spacing system.
Diagram by Elliot Dahl
  • For designers/developers: less decision making and guesswork. Developers can implement designs faster with a shared spacing system.
  • For end users: a more consistent product with better legibility and information hierarchy.

Spacing system proposal

This spacing system is based on the popular 8px grid system. It has become the standard because of how easy it is to work with. Bryn Jackson’s 8-Point Grid post goes over benefits and implementation in detail. I’ll also add that it plays nicely with a 4px grid for typography. Currently, all of the line-heights in the proposed type scale are divisible by 4.

This spacing system was designed to provide just the right amount of options while not being too restrictive.

Name px rem
Grid Unit 0.5 4px 0.5
Grid Unit 1 8px 1
Grid Unit 1.5 12px 1.5
Grid Unit 2 16px 2
Grid Unit 3 24px 3
Grid Unit 4 32px 4
Grid Unit 5 40px 5
Grid Unit 6 48px 6

Alternatively, here is a visual representation:

The spacing system visually represented as rectangles.

By using a naming convention that is based on the actual spacing value, we can make it easier to remember and use. For example, you can remember that “Grid Unit 2” is equal to 16px, as long as you know that 8px is the base unit.

Here’s an example of the spacing system implemented with CSS custom properties:

:root {
    --grid-unit: 8px;
    --grid-unit-05: calc(0.5 * var(--grid-unit)); // 4px
    --grid-unit-10: calc(1 * var(--grid-unit));   // 8px
    --grid-unit-15: calc(1.5 * var(--grid-unit)); // 12px
    --grid-unit-20: calc(2 * var(--grid-unit));   // 16px
    --grid-unit-30: calc(3 * var(--grid-unit));   // 24px
    --grid-unit-40: calc(4 * var(--grid-unit));   // 32px
    --grid-unit-50: calc(5 * var(--grid-unit));   // 40px
    --grid-unit-60: calc(6 * var(--grid-unit));   // 48px
}

This also makes it easy to create exceptions by using something like calc(10 * var(--grid-unit).

I’ve found that abstract naming like t-shirt sizing (lg, xl, xxl, etc.) is not scalable, and arbitrary numerical values can be confusing if they don’t relate to the actual value.

How do you apply a spacing system?

A diagram showing how the spacing values can be applied to UI

Generally speaking, you can apply these values to padding, margin, height, and width. The most commonly used values are divisible by 8 (e.g. 32, 24, 16, etc.). Occasionally, more control is needed over typography, icons, or some elements within a component. For this reason, 4px and 12px have been included.

In his excellent article, Space, Grids, and Layouts, Elliot Dahl describes two methods of applying a spacing system — element first and content first.

  • Element first: in this method, the dimensions of the element take priority over the content inside. For example, the height of a button, text input, or select should all have a fixed value (e.g. 32px). The content doesn’t change the height.
  • Content first: in this method, the content takes priority. Instead of setting a fixed height or width, the content dictates the dimensions. We use a value from the spacing system to determine the padding.

A note on grids

Grids and spacing are tightly coupled. As explained in the intro, grids and layout are composed using a spacing system. There are two types of grids — regular grids and a layout grids.

Regular grids can be thought of as simple graph paper laid on top of your design. They can be helpful when you’re trying to adhere to an 8px spacing system like the one I proposed. You can easily set these up in your design tools (Figma, Sketch). There’s even a simple 8px grid style available in the WordPress Foundation Figma library!

Regular grid from the Sketch documentation

Layout grids are rooted in traditional graphic design and are made up of columns, rows, and gutters. In web design, they are closely related to breakpoints and responsive web design. These can also be set up in your design tools (Figma, Sketch).

Because of the complexity of layout grids and implementing them in WordPress, I suggest we start with the proposed spacing system. Eventually I’d love to see a comprehensive, consistent layout grid in WordPress.

Layout grid from the Sketch documentation

A note on density

Density can be used to change the spacing based on the needs of the interface. Have plenty of room on the page? Use looser spacing. Need to process and take action on large amounts of information? Use dense spacing. I believe there’s an opportunity to create a simpler system to address density consistently.

Right now there are large, normal, and small buttons.

Large, nomal, and small WordPress buttons.
Currently, WordPress has large, normal, and small buttons. You can see that they are very similar.

We can consolidate those sizes into twoNormal and Dense. The current sizes are pretty similar, and it’s not clear when to use each one. Using Normal and Dense has several benefits over the current sizes:

  • Reduces overhead of maintaining button styles and alignment with surrounding elements.
  • Makes it clear when to use each one. Normal is the default, but Dense can be used when space is tight.
  • By using the proposed spacing system, we can increase the tap/click area on buttons and other elements.

If we take that concept a step further, we can apply Density to more than just buttons. We can apply it to text inputs, selects, tables, and more. Here’s a simple example of what we could implement:

An example of density being applied to UI

Implementation

Integrating the spacing system doesn’t need to happen all at once. Start small, and use it as a part of your design process. Adding Sass variables or CSS custom properties will make using this system easier. I also suggest that you change your default “nudge” amount to 8px in the design applications you use (Figma, Sketch).

Lastly, I’ll add that iterative steps are already being taken to address alignment and spacing (e.g. Trac ticket #48420). That ticket from @afercia is a great first step to thinking more about spacing holistically.

Next steps and feedback

Luckily, some parts of WordPress are already using the 8px spacing system, but its use has not been documented yet. Gutenberg is already using Sass variables with 8px values. Next, we should document this system if we decide to proceed. Then we can work on adding variables to both WordPress Core and Gutenberg.

I’ve been using this spacing system with several projects and it seems to be working well. What do you think?