DEV Community

Cover image for Understanding Margin Collapse in CSS
Moronfolu Olufunke
Moronfolu Olufunke

Posted on

Understanding Margin Collapse in CSS

Margin and how it collapses was one of the things I had it rough processing and understanding when I first started out writing CSS.

More times than necessary, I got unwanted results because of it, so here I am trying to demystify some of its basic rules so you don't get stuck like I used to - hopefully I don't bore you out too much.

Image showing a box model concepts

Margin together with content, padding and border make up the core concepts of the box model. But Margin's ability to produce unexpected and perhaps frustrating results has put it in really bad light over the years - so bad that Max Stoiber once wrote how harmful Margin is in his blog post - Margin considered harmful. haha

So What Really is Margin?

To most developers, margin is that quick and handy CSS property that lets them center a block or inline-block element without much hassle but in the real sense all Margin needs to do is add space around an element!

In Margin's quest to add this space, it can accept positive values as well as negative values. While the negative value allows you to pull an element outside of its parent the positive value instead will enable you push an element further down.
This seemingly simple and perhaps innocent feature is responsible for some of the quirks and awesomeness that is associated with Margin.

Margin Collapse

Notable among some of the unexpected results you con get from using Margin is Margin collapse. Understanding when and how Margin collapse happens could save you hours of wasted time and avoidable or minimized headache.
Below are some of the rules that will help you get around understanding Margin Collapse.

Margin Collapse Rules:

RULE 1: Only Vertical Margins collapse.

What this means is that block level elements like <div> and <section> etc, stacked on top of each other with the same amount of margins between them will have both margins collapse to only have just one margin emerge.
Here is an example that should give insight to the explanation above:

   div {
       background: rebeccapurple;
       color: #ffffff;
       height: 100px;
       margin-bottom: 30px;
       margin-top: 30px;
       width: 100px;
   }
Enter fullscreen mode Exit fullscreen mode
<div>This is a div</div>
<div>This is another div</div>
Enter fullscreen mode Exit fullscreen mode
Can you guess what the results will be?

You are probably hoping to get a 60px margin (30px + 30px) between the bottom and the top of the first and second div but interestingly, it doesn't work like that.
As explained before, because these two margins have the same amount of value, all they did was collapse to become 30px!
Vertical Margins Collapse Demo

As you can see from the screenshots above, the two margins did collapse.
Below is a link to the codepen live demo, if you'd like to see it in action.
Codepen Live Example

What would have happened if these div were placed side by side i.e horizontally, with the same amount of margin between the right side of the first div and the left side of the second div?

   div {
       background: rebeccapurple;
       color: #ffffff;
       display: inline-block;
       height: 100px;
       margin-right: 50px;
       margin-left: 50px;
       width: 100px;
   }
Enter fullscreen mode Exit fullscreen mode
<div>This won't collapse</div>
<div>This won't collapse either</div>
Enter fullscreen mode Exit fullscreen mode

Horizontal margin example
Horizontal margin example
Horizontal margin example
HorIzontal Margin Demo

What happened here?

The block elements were turned into inline-block elements and they were both given equal amount of margin. As opposed to the collapsing we saw for the vertical block elements, these div did not collapse, instead as seen in the image above, we got two div separated by a 100px margin i.e 50px from the right side of the first block element and 50px from the left side of the second element.
This happened because according to our first rule, only vertical margins collapse, horizontal margins do not.

RULE 2: The biggest margin wins:

As opposed to our first rule where equal margin collapses to one margin.
Here, when vertical elements are stacked on top of each other with varying margins, the bigger margin will always win.
No matter how minuscule the difference between the two margins is, the smaller margin will will always be enveloped by the larger margin.

<div>The smaller margin gets lost</div>
<div>The bigger margin wins</div>
Enter fullscreen mode Exit fullscreen mode
div {
  background: peru;
  color: #ffffff;
  height: 100px;
  margin-bottom: 30px;
  margin-top: 50px;
  width: 100px;
}
Enter fullscreen mode Exit fullscreen mode

The bigger margin wins example
Bigger margin wins Demo
You may have been expecting the margin between the bottom of the first div and the top of the second div to get added up to 80px but according to the "biggest margin winning" rule, we got a different result where the bigger margin (50px) enveloped the (30px).
Thus, we only have 50px of margin between the two divs.

RULE 3: Only Adjacent elements collapse

According to the Oxford dictionary, adjacent means:

"next to or adjoining something else".

This relates to margin collapse in the sense that only elements that are next to one another can collapse.
In effect, line break (<br>) or any of the other box-model features i.e padding or border can be seen as walls which will prevent any form of collapse from happening between the elements margins.

Below is an example:

<div>The margin won't collapse</div>
<br>
<div>The margin won't collapse either</div>
Enter fullscreen mode Exit fullscreen mode
div {
  background: peru;
  color: #ffffff;
  height: 100px;
  margin-bottom: 30px;
  margin-top: 30px;
  width: 100px;
}
Enter fullscreen mode Exit fullscreen mode

Referencing our first rule - Vertical Margin collapse rules - you would expect the margins between the two elements to collapse but this won't happen because of the "wall" i.e line break tag (<br>) we have between the two elements.

Adjacent margin example demo
Adjacent Margin Demo

If this line break tag (<br>) was removed, we would have gotten the same result as we had in the Vertical Margin Collapse Rule example.


This is not an exhaustive list of all the rules to know to not encounter the margin collapsing quirks, this is just meant to give you an insight into some of the things you may encounter and give you a better understanding as to how to tackle others.

Cheers and happy coding.

Top comments (6)

Collapse
 
pspaczek profile image
Przemek Spaczek • Edited

What about display:flex? If I good remember in flex margins collapse it doesn't work.

Collapse
 
moerayo profile image
Moronfolu Olufunke

Hello Przemek,

You are right, when you add display:flex to an element i.e parent element, the margin of the children element will not collapse.

This is because, margin collapse can only happen in the default layout of the web and display:flex isn't part of the default web layout.

Collapse
 
huydzzz profile image
Pơ Híp

article awesome

Collapse
 
moerayo profile image
Moronfolu Olufunke

Thank you

Collapse
 
cariehl profile image
Cooper Riehl

Thanks for this explanation! I never fully understood how margin collapse works, so I definitely learned something 😊

Collapse
 
moerayo profile image
Moronfolu Olufunke

You're welcome...

I'm glad you found the article helpful.