Spacing Components

See this link for an always-current, potentially more dev-friendly read.

First, some clarifications:

  • Margin is a css property for spacing outside of a component. A div with a yellow background and margin will not see the yellow background in the margin spacing.
  • Padding is a css property for spacing inside of a component. A div with a red background and padding will see the red background in the padding spacing.

So, when building a component, how should the two properties be used?

Well, for the most part, components are a powerful construct because they only care about themselves, and are not concerned about the world around them. So, padding should be used for all spacing needs. This maximizes reusability and separates their concerns from the world outside them.

But in the real world, we do need spacing outside of components for composing them into pages and scenes. And this is where margin creeps into component code: for spacing compositions of components.

Should margin really be the concern of a component though? Given my <Button /> component, should it really accept a marginTop or marginLeft prop? How about on a bigger scale? Should ALL of my composite components accept these margin props? That doesn't seem scalable.

A better solution might be to wrap my Button component with another component whose sole purpose is to apply margin. Something like:

Nice! We have a clear separation here, and we haven’t muddied our Button API.

This Margin component visually breaks down though (yes, it is a totally contrived example):

The above button group is pretty difficult to skim and understand the spacing. We can do better!

And this is what I’ve settled on using for page/scene spacing: the <Space /> component. Space accepts a single size prop, which is used to set its flex-basis. Note: I can get away with only using flex-basis because I use flexbox exclusively, in React Native and web.

Conveniently, this ends the debate of margin-bottom or margin-top for my code.

Try it

Feel free to try constelation-space on web and native, or make your own

Credits

  • props to kilvin/Spacer.js for using flex css attribute and a size prop.
  • Android Studio actually has a Space widget in their wysiwyg editor

Originally publish in the react-playbook