Łukasz Makuch

Łukasz Makuch

Don't marginalize reusable components!

I'd like to share with you a low-effort technique to get the perfect white space every single time.

Let's start from the very beginning.

This is the workspace where we are going to build components.

The workspace

And this is our first component. It's a button.

A button

We will also need a couple of other components, like a table and an input field.

A table An input field

This is an empty screen where we will lay out the components.

An empty screen

Let's place three input fields, a table and a button on the screen.

The first attempt

Oops! We forgot about a layout! 😅 So let's say that the button and the input fields are in a single row and the table is placed below them.

The second attempt

The items are aligned to the right.

The third attempt

We want to introduce some white space between the form and this table.

A table

The first idea may be to add a margin. Let's try it out.

A table with some margin

Now, the whole screen looks like this. Getting better!

spacing attempt1

Just the input fields are too close to each other. Adding some margins worked in the past, so maybe it will work here as well?

An input with some margin

Yay! It all looks good now!

spacing attempt2

Does it mean that adding some margins here and there actually did the job? 🤔 It depends! To illustrate why, let's say that after some time we want to place the input fields below each other.

This is what happens when we simply change the layout from horizontal to vertical.

spacing attempt3

Oh no! ☹️ The input fields are misaligned and there isn't enough space among them.

But that shouldn't be hard to fix, right? Let's change the input field margin from right margin to bottom margin.

An input with bottom margin

Ha! It worked!

spacing attempt4

Oh snap! 😬 The login screen just broke!

A broken login form

It used to look like this.

The current login form

But what exactly is broken?

If we just look at screen visible above, ignore the underlaying component architecture, and try to point out the biggest component, it will be this one.

Whitespace on white background

Oops, wrong background! 😉 Let's bring it to the workspace.

Just whitespace

Yes, it's just the white space.

What I'm trying to say is that the white space should be treated with respect.

Similarly to how we wouldn't chop a table up and distribute it among components that happen to live nearby, the space between components deserves to be a component as well.

Let's see how we can decompose the white space visible above into a set of reusable components.

Here we have a horizontal container that defines a gutter, that is the space between elements we put inside it.

The horizontal form grid

We can now remove all the margins we previously added.

A table

An input field

It's enough to put these elements inside a spacing container that defines the proper gutter to make them look good.

The horizontal form grid with some items

In order to keep these elements in the center of the screen, we need to use a centering container.

Centering container

It's simple. Whatever we put inside it, it will land in the center.

Centering container with items

We're ready to rebuild this view in a robust way.

spacing attempt4

The first component will be a vertical version of this container. It gives us the gutter we want.

The horizontal form grid

Here it is.

The vertical form grid

We can simply drop there any reusable components, that is components that have no margins.

The vertical form grid with some items

The space between the form and the table is larger than the space among form elements. It's a signal that there's a different container with a wider gutter. Here it is, as a component.

The section grid

Again, we just place the smaller components inside.

The section grid with some items

The grid based layout on the screen

The big advantage of such a setup, where "visible" components have no margins at all and "invisible" space is made of components as well, is that all these components are truly reusable and may be composed. Including the white space!

Let's take a look at this screen.

Another set of components

We can build it without introducing any new components or styles!

There are three sections. We can reuse the section container to get the wide gutter we want.

Another set of components with a visible section grid

Similarly, to get the space among form elements right, we can reuse white space components we already have. No extra work required!

Another set of components with a visible form grid

To sum it up, we stopped doing this this way.

An input with some margin

We no longer use margins in reusable components. Instead, we extract white space components.

The horizontal form grid

Thanks to this simple trick, we can now build new, visually consistent screens without introducing any new styling rules.

Another set of components

spacing attempt4

The current login form

All the combinations will always have the proper and consistent white space.

Moreover, we made accidentally broken layouts a thing of the past! 🎉

A broken login form