Margin collapsing is a tricky thing that usually pops up at the worst time. I’ve had issues with it when laying out content for a something like a slideshow hero where there will be multiple images and text containers per slide and the content below the slide needs to be brought up to lay over top of the image ever so slightly.
There are 3 basic reasons that the top and bottom margins of elements will collapse:
[codepen_embed height=”637″ theme_id=”0″ slug_hash=”emmaKL” default_tab=”result” user=”aicarlson”]See the Pen <a href=’http://codepen.io/aicarlson/pen/emmaKL/’>emmaKL</a> by Andrew Carlson (<a href=’http://codepen.io/aicarlson’>@aicarlson</a>) on <a href=’http://codepen.io’>CodePen</a>.[/codepen_embed]
Adjacent Siblings:
From the MDN: The margins of adjacent siblings are collapsed.
This means that if you have two sibling elements that have margins, those margins will be collapsed into the value of the largest margin. So for example, if you have two elements such as paragraphs or divs, both with top and bottom margins of 15px, you would expect them to be separated by 30px but the margins would collapse down to just 15px.
If you had two elements, the first with a top and bottom margin of 25px and the second with a top and bottom margin of 15px, the bottom and top margins would collapse to 25px instead of the expected 40px.
Solution:
Set a width on the element in question (whether it be in px, % or em) and then float it to the left or right.
Parent and First / Last Child:
From the MDN: If there is no border, padding, inline content, or clearance to separate the margin-top
of a block with the margin-top
of its first child block, or no border, padding, inline content, height, min-height, or max-height to separate the margin-bottom
of a block with the margin-bottom
of its last child, then those margins collapse. The collapsed margin ends up outside the parent.
This one is pretty self explanatory except for the fact that the collapsed margin ends up outside the parent. For example, if you have a parent div
with no top or bottom margin, and then a child div
immediately inside, without any text in between that has margin-top
(probably in order to push the child div
down a bit), that margin-top
will end up outside the parent div
, pushing the whole container down.
Solution:
Set a transparent, 1px border-top on the parent element. border-top: 1px solid transparent;
Empty Blocks
From the MDN: If there is no border, padding, inline content, height, or min-height to separate a block’s margin-top from its margin-bottom, then its top and bottom margins collapse.
I’ve actually never run into this instance before, but it may come up if you have an empty element that you’re using as a spacer. If you have an element with a top and bottom margin of 100px with nothing inside, and no height to separate the margins, they’ll collapse into 100px, rather than the expected 200px.
Solution:
Try to add a 1px border, content or height.
One Size Fits All
If all else fails and for some reason you can’t use one of the above solutions in your code, keep in mind that elements that are either floated or absolutely positioned will never collapse margins. This may be an easy way to get around margin collapses if you can declare a width on an element and then float it and clear it later on.