How to make better CSS components

Sergey Gultyayev
3 min readMay 31, 2022

While CSS development seems easy we as developers tend to make the work harder to ourselves by designing fragile constructions. How can we improve that?

1. Make spacing predictable

Following a simple rule you can make debugging in CSS much easier for every developer in your team. The rule dictates to use margin for bottom and right sides, whereas use padding for top and left sides.

Not only it makes spacing more predictable, but also you won’t get into the margin overlap problem in the vertical spacing. Indeed this should not be blindly followed and when you need a horizontal spacing you would use the margin for right and left sides. This rule mostly applies for the spacing between elements.

2. Don’t make any assumptions on positioning

When developing components such as cards or similar components that are usually grouped and have some spacing between it might be tempting to define spacing between those elements as part of the component itself e.g.

.card {
padding: 20px;
border-radius: 15px;
margin-right: 20px; // <-- here
border: 1px solid #eee;
}

However, this makes this element fragile as we might need to use it elsewhere and thus would have to override this style. Some time later we might change the spacing of the component and thus break all our end users (other components/pages). We should never do that.

Instead, a host rendering those components should attach its desired spacing configurations. This way all usages are independent and spacing can be updated with no fear.

3. Use modern CSS features

Imagine we have this common case with 3 cards in a row where we need to have some spacing between them.

The naive approach that developers have been using for a while is to use the flexbox on the parent container, margin-right on the cards and add a negative margin to the parent container.

While this works, there is a better solution — grids.

While new CSS features adoption isn’t fast the grids have been there for a while and now crossed the 90% of the worldwide support so we can use it.

We need to simply define the parent container as grid and set a gap

.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 20px;
}

This way we will always have 20px gap between the cards vertically and horizontally without the need for workarounds such as negative margins. And it also doesn’t add any gaps in case there is not enough elements!

--

--

Sergey Gultyayev

A front-end developer who uses Angular as a main framework and loves it