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.
And this is our first component. It's a button.
We will also need a couple of other components, like a table and an input field.
This is an empty screen where we will lay out the components.
Let's place three input fields, a table and a button on the screen.
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 items are aligned to the right.
We want to introduce some white space between the form and this table.
The first idea may be to add a margin. Let's try it out.
Now, the whole screen looks like this. Getting better!
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?
Yay! It all looks good now!
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.
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.
Ha! It worked!
Oh snap! 😬 The login screen just broke!
It used to look like this.
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.
Oops, wrong background! 😉 Let's bring it to the workspace.
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.
We can now remove all the margins we previously added.
It's enough to put these elements inside a spacing container that defines the proper gutter to make them look good.
In order to keep these elements in the center of the screen, we need to use a centering container.
It's simple. Whatever we put inside it, it will land in the center.
We're ready to rebuild this view in a robust way.
The first component will be a vertical version of this container. It gives us the gutter we want.
Here it is.
We can simply drop there any reusable components, that is components that have no margins.
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.
Again, we just place the smaller components inside.
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.
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.
Similarly, to get the space among form elements right, we can reuse white space components we already have. No extra work required!
To sum it up, we stopped doing this this way.
We no longer use margins in reusable components. Instead, we extract white space components.
Thanks to this simple trick, we can now build new, visually consistent screens without introducing any new styling rules.
All the combinations will always have the proper and consistent white space.
Moreover, we made accidentally broken layouts a thing of the past! 🎉