Margin collapse — or; why your child element is moving the parent

Gary Wood
FED || Dead
Published in
2 min readOct 15, 2015

--

You’re building a new landing page at work. You’ve fleshed out the basic template, and you’re applying some generic layout styles. You want your content to sit within a 1000px container, centred to the page, so you style up something like this;

.my-parent-element {
width: 1000px;
padding: 0;
margin: 0 auto;
background: #5981a5;
}
.my-child-element {
padding: 10px;
margin: 10px;
background: #f4f4f4;
}

What you are now looking at is image one below, but what you were probably expecting is in the second image… What the hell, right?

“Well if you were a man, I’d punch you. Punch you right in the mouth.” — Ron Burgundy

The reason for this is what is known as ‘margin collapsing’ — top and bottom margins of block elements can be ‘merged’ by the browser, and the largest of these is used (which is very logical if you think about it). You can read a better explanation at Mozilla.

Fear not, though, this is very quick and easy to fix. Here are a few options for how to remedy this, the first of which is my preferred technique.

Add a padding/margin hack to the parent to force your parent to behave. If you add 1px of padding-top, and -1px of margin-top, your parent is now doing as the child wanted — just like in real-life…

.my-parent-element {
width: 1000px;
padding: 1px 0 0 0;
margin: -1px auto 0 auto;
background: #5981a5;
}
.my-child-element {
padding: 10px;
margin: 10px;
background: #f4f4f4;
}

Alternatively, you can add an overflow: auto or hidden to the parent (but these both bring their own problems)

.my-parent-element {
width: 1000px;
padding: 0;
margin: 0 auto;
overflow: auto;
background: #5981a5;
}
.my-child-element {
padding: 10px;
margin: 10px;
background: #f4f4f4;
}

You could also have any element inside the parent, before your child element, which contains content (even an  ) should also prevent this — but do you want to be adding unnecessary elements when using a hack is already bad enough, eh?!

Finally, does your design/layout really require margin on the child element? Could you instead apply padding to the parent element in order to position the child correctly? hint hint: box-sizing

Here’s a question for you — did you notice anything weird in my examples above? Have another look at the images and example CSS, and ask yourself why the ‘blue border’ doesn’t extend all the way around the child element…

--

--