Ensuring consistent spacing in your UI

April 19, 2018 | Tim Petricola | 4-minute read

Drivy is growing, and the impact of this is particularly reflected in the evolution of our visual identity, conveyed by Drivy’s UI.

Having more and more people involved in new features (product managers, copywriters, designers, developers, …) means having more UI updates on the website. To make things easier, we’ve recently started working on Cobalt, Drivy’s internal design system.

Design systems are a broad topic. This post will only focus on dealing with whitespace across the website.

The problem

In the past, we didn’t have a process for deciding on what value we should use for a given whitespace. Sometimes, a designer would choose a specific value or the developer might decide to take the time to make it pixel perfect. Other times it would just be a question of getting a feeling for “what looked right” during implementation. And then we’d end up with feedback such as “try adding 1 or 2 pixels there”.

This would lead to two main frustrations:

  • developers and designers would spend time searching for the perfect value™
  • visual approximations and inconsistency would appear across pages

Choosing values

We knew we wanted to establish a fixed set of values that we could use for all whitespaces. But how to choose them?

We experimented with some of our components (a car card, new landing pages, our new booking page etc.) to see what could work. This also meant playing with typography to find the proper line-heights for every font style. In doing so, we ended up with a 4px baseline.

We then extracted the main values from this set of experimental components. When it made sense to do so, we homogenized and merged some of the values to end up with a reduced set. Several components and a bit of tweaking later, we now use this set of values:

spacing values

Enforcing it

Having a theoretical set of values is great. But how do you make sure that they will be used?

This is not an issue for our UI team as they are at the core of the design-system project and know what values to use. But what about developers who had been less involved? And, is it now necessary for them to know the specific value of a given spacing as they implement it?

We don’t think so.

We got inspired by what Shopify are doing with Polaris and ended up writing a custom Scss function. Whenever someone needs to add some spacing, they can write the following:

.component {
  margin-bottom: spacing(tight);
}

And the implementation is quite simple:

$unit: 4px;

$spacing-data: (
  none: 0,
  unit: $unit,
  extra-tight: $unit * 2,
  tight: $unit * 4,
  base: $unit * 6,
  medium: $unit * 8,
  loose: $unit * 12,
  extra-loose: $unit * 16
);

@function spacing($variant: base) {
  $value: map-get($spacing-data, $variant);

  @if $value == null {
    @error "Spacing variant `#{$variant}` not found.";
  }

  @return $value;
}

Dealing with edge cases

Components with a border

But what if a component has a bottom border of 1px, setting the whole baseline off? There are various solutions to this issue, such as dropping borders in favor of box shadows. But our approach is quite simple: compensate by removing some spacing.

.component {
  $border-width: 1px;

  padding-bottom: spacing(tight) - $border-width;
  border-bottom: $border-width solid #fff;
}

Component with user uploaded media

We have to accept that the baseline will not be respected. In our case here at Drivy, this occurs when we display pictures uploaded by users, where we want to respect the ratio.

Car Card
The image has a height of 222px, which does not conform to the base 4 rule.

Conclusion

Our design system is still young and we have a lot of things to improve on and decide about. In the same way that we chose spacing values, we also have conventions for typography and colors.

Seeing as we have a lot of pages in our application, it’s not feasible to migrate the whole site to Cobalt at once. But we’re very excited to slowly roll out our new system throughout the application!

👍  Like this post? Join Drivy's engineering team! View openings