2

I have very simple code for beginning:

<!doctype html>
<head>
</head>
<body>
<style>
.master {
    background: green;
}
.master div {
    background: red;
}
</style>
<div class="master">
<div>
abc
</div>
</div>
</body>
</html>

I put it also on JsFiddle. Only inner (red) div is visible because there is no margin or padding set so inner div takes the whole space of .master div. That's clear.

I would like to set for .master div margins to 20px so I could do it this way:

.master div {
    background: red;
    margin: 20px;
}

But I would expect that I have both div visible (red and green) but in fact only red color is visible and green is visible only on left and right - JsFiddle.

I know how to solve it (in this case I can set padding for .master div to 20px I could do something like this:

.master {
    padding: 1px 0;
}

and I'll have the same effect (or almost the same effect - 1px difference) as you see at JsFiddle or I could set padding for .master div instead of using margin for inner div

Questions:

  1. Why simple adding margin for inner div doesn't make that margin is set as expected (both green and red visible) and why adding even small padding fix it?

  2. Why behaviour for it is different for top and bottom margin and for left and right margin ?

  3. Is this issue has any name?

  4. Are there any other common cross-browser solutions?

If it is explained in external source you can also add link to external resource.

I'm a bit ashamed that I ask about such simple thing, but I always solve this using simple padding (as showed in the question) and it worked.

Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291

1 Answers1

4

This effect is due to the "Collapsing Margins" specification. Here's the explanation from the W3C:

“In this specification, the expression collapsing margins means that adjoining margins (no non-empty content, padding, or border areas, or clearance separate them) of two or more boxes (which may be next to one another or nested) combine to form a single margin.”

Margin collapse only occurs with vertical margins on adjacent or nested elements.

Answers to your questions:

  1. Adding margins to the inner div causes a margin collapse with the margins of the outer div. They are combined into one margin. Setting a padding on the outer div gives it a block formatting context and separates the elements, therefore un-collapsing the margins.

  2. Margin collapse only occurs on vertical margins.

  3. The effect is called "collapsing margins".

  4. The only cross-browser "solution" is to give the parent element a block formatting context by adding padding or overflow: auto/hidden.

See this article on SitePoint for more information

JoeJ
  • 920
  • 1
  • 6
  • 17
  • 1
    Regarding (1), setting `overflow: {auto|hidden}` will also establish a block formatting context, similar to adding padding or a border. – Marc Audet Jul 23 '14 at 11:59
  • @JoeJ Thank you for explanation. I thought it's only for adjacent elements and not nested. So it seems I always used the correct solution not even knowing about it. – Marcin Nabiałek Jul 23 '14 at 12:17
  • @MarcinNabiałek Yes, you did. Glad I could help. – JoeJ Jul 23 '14 at 18:31