Skip to main content

Where do you put spacing on design system components?

I work on design systems now. It scratches a lot of itches I have, most importantly organizing and standardizing things, as well as baking accessibility in at both the design and development layers.

My very cool boss is working on updating our grid system, and with that comes conversations about vertical rythm.

If you’re not familiar, vertical rhythm is a way to consistently add vertical spacing between things by providing predefined measurement values. Typically these measurement values are derived from an underlying source of logic such as a modular scale.

The idea for providing measured stops for vertical spaces is a method for both designers and developers to work from a common source of truth. It enforces consistency across different parts of a website, as well as other websites that also utilize the design system.

Consistency is an important thing in any design system. There are also a couple other big-picture considerations our design system needs to accommodate, which in turn affects our approach:

In terms of a mechanism for communicating vertical spacing in Sketch, there are a few approaches we were thinking through:

Manually moving things around until they “look right”

This is pure chaos and cannot scale.

Bake a single vertical space into each component

The idea here is we collectively decide that each component only uses one measurement to define how far away it should be placed.

A card component with a light blue rectangle placed on top, indicating a set amount of vertical spacing.

I’m of the school of thought that spacing should always go on the top, so it’d be adding negative space to the top of each component symbol.

The problem with this approach is it is too limiting to be usable in the real world. One set measurement won’t meet the myraid use cases of an unknown number of unknown designers working on an unknown number of projects with unknown content needs.

If it is too limiting, it will be ignored. This means vertical spacing gets moved back into manually moving things around until they “look right” territory.

Make vertical spacing a component prop

The idea here is the space on top of each component is a toggleable set of distances, and these distances are a set of codified values. A designer can can then toggle the prop to use a spacing value that works best for their needs.

Three card components with a light blue rectangle placed on top of each. Each rectangle has a different height, indicating predefined range of vertical spacing values.

This is my preferred approach! Threading spacing abstraction into a component in a systemized way like this tightly couples vertical spacing with each component instance.

If we were using Figma, this would be the end of the post. Its Variants functionality can handle exactly this sort of thing with elegance and grace. Unfortunately, we’re not using Figma.

To accomplish this sort of thing in Sketch, we’d have to create a symbol for each component with each spacing value, and then each variant of the component. In all fairness, you need to also do this in Figma to get Variants set up.

The real issue, however, is how it is exposed to the designer using the design system component.

Sketch exposes variants as submenus, so it takes a lot of digging to get what you need. This is friction, which means it decreases the likelihood a designer will use both the component and the design system.

TBD
This is a simplified example and it’s already too awkward.

Compare this to Figma, which exposes this information in a far more ergonomic way:

A compact component panel, showing four property dropdowns and their currently selected values. The properties and their values are: variant and primary, mode and light, state and default, and spacing and small.
Ahhh, that’s the stuff.

Surface area

While creating mature components in Sketch and Figma both take a lot of upfront work, the way a designer interacts with the component differs based on design choices the app developers made about how components are constructed. This in turn affects a designer's experience in working with the design system as it manifests in a design tool.

Here's how Sketch’s hierarchal component nesting approach compares to Figma’s more categorical toggle approach:

Sketch

An extremely tall mind map. The parent node is labeled Sketch Button Component, and has child nodes 6 levels deep. The 6 node levels are priority, icon, light/dark mode, state, on light/dark, and then space on top. There are hundreds of nodes due to the branching complexity.
The fact that this is incomprehensible is the point. Full-size, PDF (43 kb).

Figma

An extremely tall mind map. The parent node is labeled Figma Button Component, and has child nodes 6 levels deep. The 6 node levels are priority, icon, light/dark mode, state, on light/dark, and then space on top. There are hundreds of nodes due to the branching complexity.
A far shallower surface area that still gets you what you want.

Spacer components

Since component props are off the table, the only real sensible thing to do is create a documentation “meta” component that captures these spacing values.

8 light blue squares whose sizes proportionately scale upward in size.

Designers can then take these spacing components and use them to “Lego” components on a design together. This approach:

Spacer divs

Spacer divs is a development technique that was in vogue a few months ago. As an old-school web nerd, it feels awkward and gross—like table-based layout 2.0.

Going with the spacer component approach feels like we’re suggesting using spacer divs to match. I’d much prefer the components to have a vertical spacing prop on the code end of things that maps to an abstracted margin or padding value (A CSS Custom Property fed by a design token, if you’re doing it right).

Talk to people

Design systems are for interfaces, but interfaces are worked on by people. To disincentivise using spacer divs and use component props instead, you’ll want to have conversations with your design system’s developers. I prefer frequent communication and collaboration to do this.

Until design tools mature more and intent can be more easily carried through, we need to consider: