Nested div with margin top set causes scrollbar to appear

Let’s say I have this small HTML snippet:

<div id="outer">
  <div id="inner">
    <div id="inner2">foo bar</div>
  </div>
</div>

I also have these styles defined:

#outer {
  height:100px;
  overflow:auto;
  background-color:#EEE;
}
#inner {
  height:100px;
  background-color:#AAA;
}
#inner2 {
  margin-top:5px;
}

With this setup, scroll bars appears with the outer div:

sample result

Why does the nested inner div causes this scrollbar to appears?

I can remove the scrollbar by removing the margin-top rule, but this would cause side effects.

Here is a jsfiddle that reproduces the issue: http://jsfiddle.net/stevebeauge/PTA85/

[edit] : my actual issue is solved by replacing margin-top by padding-top, but I’m looking for an explanation, not only the solution.


solution

This is occurring because the margins are collapsing.

Box Model 8.3.1 Collapsing margins

In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.

When two or more margins collapse, the resulting margin width is the maximum of the collapsing margins’ widths. In the case of negative margins, the maximum of the absolute values of the negative adjoining margins is deducted from the maximum of the positive adjoining margins. If there are no positive margins, the maximum of the absolute values of the adjoining margins is deducted from zero.

Possible workarounds:

Replace the margin with padding (example).

Add overflow:auto to #inner (example)

Float #inner2 (example)

Change the display of #inner2 from block to inline-block (example)

For additional information see The visual formatting model - Block formatting contexts.