DEV Community

Cover image for Why I fell in love with margin-top
Andreas Riedmüller
Andreas Riedmüller

Posted on

Why I fell in love with margin-top

When you write CSS, chances are good you constantly struggle with spacing. If you never had a situation where you needed to open up the inspector to find the origin of vertical spacing, this article is not for you.

To avoid this struggle, I found that one very simple rule works surprisingly well for me:

Use margin-top only.

I’ve been following this rule now for more than three years and in many different projects, and it proves to be just helpful.

You need to decide which element gets vertical spacing?
Add margin-top to the lower element.

You want to increase/decrease some vertical spacing?
Change the margin-top of the lower element.


Here are some best practices and exceptions I came along:

The next/subsequent sibling combinator

Sometimes you want to define spacing below an element. For example a heading that needs some space between itself and the next element, whatever it is. In this case you can use the next-sibling combinator

.element + * {
  margin-top: 1rem
}

/* Instead of: */

.element {
  margin-bottom: 1rem
}
Enter fullscreen mode Exit fullscreen mode

If you have multiple inline-block elements below each other by the help of line break elements you can use the subsequent-sibling combinator:

.inlineBlockElement
<br>
.inlineBlockElement
<br>
.inlineBlockElement
Enter fullscreen mode Exit fullscreen mode
.inlineBlockElement ~ .inlineBlockElement {
  margin-top: 1rem
}

/* Or if you don’t know the next elements class */
.inlineBlockElement ~ *:not(br) {
  margin-top: 1rem
}
Enter fullscreen mode Exit fullscreen mode

Horizontal spacing

This rule is meant for vertical spacing, but you can apply it to horizontal spacing as well: Use margin-left when possible.

But be careful with inline-block elements that may break into the next row. In this case using margin-right is better as the spacing on the right is not visible.

margin-left
margin-left

margin-right
margin-right

Exception: content added with :before

There is no rule without exceptions, here is one I stumbled upon.

Let’s say you have an icon above a paragraph of text and this icon is a :before pseudo element. As the content after :before cannot be targeted using CSS you need to use margin-bottom.

<div>
  :before
  This is some content you can not easily give margin-top.
</div>
Enter fullscreen mode Exit fullscreen mode

Why not margin-bottom?

Actually, this was my first approach but I switched to margin-top for several reasons.

1. Less code navigation

Most of the time I append new elements when writing markup. When doing so my scope is this newly added element. And thus setting margin-top for this element is easier than eg. navigating to the previous elements css to set its margin-bottom.

2. The next/subsequent sibling combinator

As there is no previous-sibling selector in CSS3, you can not easily say "Hey, if there is something before me it should have margin-bottom"

3. It looks better and is shorter to write

Sure, this is not reason #1, but who wants to write "bottom" all the time?

.element {
  margin: 1rem 0 0;
}
.element {
  margin-top: 1rem;
}

/* VS */

.element {
  margin: 0 0 1rem;
}
.element {
  margin-bottom: 1rem;
}
Enter fullscreen mode Exit fullscreen mode

No headaches

This rule should make your life easier, not harder. Avoiding margin-bottom is simple most of the time, but if you encounter a situation where this is not the case, don’t take it too serious.

And of course, if there are other guidelines for a project they should always have a higher priority.

Thanks for reading, how do you cope with spacing? Do you have a similar rule? Let me know!

Discussion (5)

Collapse
dippas profile image
dippas • Edited

I use the exact opposite guideline for years in large (modular) projets, which is using margin-bottom/right and IMHO is way better,

Your examples of CSS for margin-top shouldn't be used, as it can cause a lot of issues in maintenance among others (eg: performance/speed),

Also your point #3 I really can't see the difference from you top VS bottom.

About the headaches, no headaches at all, just a matter on how to do things properly

Collapse
receter profile image
Andreas Riedmüller Author

I did use margin-bottom for some time and it has most of the advantages. Especially #1 (less code navigation) was what convinced me to switch.

You mean ~ *:not(br) right? You can also go with + br + * which is easier to understand.

Of course, with margin-bottom you don’t need the + cominator, but you will have a harder time if you have various preceding elements that need different spacing.

What are the advantages of margin-bottom that conviced you? Let me know!

Collapse
madsstoumann profile image
Mads Stoumann

I mostly use gap for spacing (flex or grid), but if needed, I tend to use margin-block-end, and then just remove it from :last-of-type.

Collapse
vladi160 profile image
vladi160

For margin-left/right u need to remove it for the :first/last-child and use float, which is the old way. Much better is with flex

Collapse
receter profile image
Andreas Riedmüller Author

Yes, especially now that gap for Flexbox is finally supported in all major browsers. Sometimes I use inline-block for simple cases to save a container element. I don’t use float for this.