4

Following is the snippet (demo on JSFiddle)

#inner {
    background-color: yellow;    
    margin-left: 50px;
    margin-bottom: 50px;
}
#outer {
    background-color: red;
}
<div id="outer">
    <div id="inner">
        test
    </div>
</div>

As can be seen in the demo, the #inner element has a margin-bottom.

I expected the height of #outer will be large enough to include the outline of #inner margin. And the output will have a red bar below the yellow bar.

However, I found the #outer's height is not changed at all though I added the rule margin-bottom: 50px for #inner.

Does anyone have ideas about this? And is there a way to ensure the content area of parent is large enough to hold the outline of its child's margin?

Also, apart from giving a hack solution, it would be great if the answer can include some explanation or links to related document/article. And why is the margin rule designed like this.

Thanks!

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Hanfei Sun
  • 45,281
  • 39
  • 129
  • 237

6 Answers6

6

What you are seeing is the collapsing margins problem.

Top and bottom margins of blocks are sometimes combined (collapsed) into a single margin whose size is the largest of the margins combined into it, a behavior known as margin collapsing.

Out of the three cases, yours is the case of collapsing margins between parent and child elements.

If there is 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.

If you add another element just after your parent div you will see that the margin ends up outside of it. The snippet below, shows you the collapsed margin:

#inner { background-color: yellow; margin-left: 50px; margin-bottom: 50px; }
#outer { background-color: red; }
<div id="outer">
    <div id="inner">
        test
    </div>
</div>
<p>You can see the collapsed margin above this text outside of the parent div.</p>

Here is the reference from the specs: http://www.w3.org/TR/CSS21/box.html#collapsing-margins


How to fix this?

The solution is given in the quoted ref text itself above. Just apply any one of these to your parent div - border, padding, height, min-height, or max-height.

Easiest way to fix this would be to add a border to your outer div:

#outer { background-color: red; border: 1px solid gray; }

Better still, apply padding to the parent div instead of the margin on inner one.

#outer { background-color: red; padding-bottom: 50px; }

Examples:

Fiddle (with border): http://jsfiddle.net/abhitalks/rrtfhyky/1/

Fiddle (with padding): http://jsfiddle.net/abhitalks/rrtfhyky/2/

Snippet (with padding):

#inner { background-color: yellow; margin-left: 50px; }
#outer { background-color: red; padding-bottom: 50px; }
<div id="outer">
    <div id="inner">
        test
    </div>
</div>
<p>Some text that follows.</p>
Abhitalks
  • 27,721
  • 5
  • 58
  • 81
  • 3
    +1 for the explanation, though a border seems like a rather intrusive fix. A more natural solution would be to change the inner element margin to outer element padding. There are a number of other ways to block margin collapse, as described [here](http://stackoverflow.com/questions/9519841/why-does-this-css-margin-top-style-not-work/9519933#9519933), though most of them have pretty adverse effects on layout so it's not just a matter of preference. – BoltClock Oct 27 '15 at 08:09
4

I had the same problem, just add overflow: auto to #outher div and it will fix the parents height

#inner {
    background-color: yellow;    
    margin-left: 50px;
    margin-bottom: 50px;
}
#outer {
    overflow: auto;   /* ADDED */
    background-color: red;
}
<div id="outer">
    <div id="inner">
        test
    </div>
</div>
Kristijan Iliev
  • 4,901
  • 10
  • 28
  • 47
1
Add This CSS

#inner {
    background-color: yellow;
    margin-left: 50px;
    margin-bottom: 50px;
    display: inline-block;
}
Jenti Dabhi
  • 870
  • 5
  • 11
0

I know this common "bug", what I would do if I were you is changing the margin into padding and put it to the outer div:

  1. My solution:

    #inner {
        background-color: yellow;    
    }
    #outer {
        background-color: red;
        padding-left: 50px;
        padding-bottom: 50px;
    }
    

Also there are 3 other possible fixes:

  1. By @Jenti Dabhi is the add the display:inline-block to the #inner div:

    #inner {
        background-color: yellow;
        margin-left: 50px;
        margin-bottom: 50px;
        display: inline-block;
    }
    
  2. By @Chris is to add overflow: auto to the #outer div:

    #outer {
        overflow: auto;
        background-color: red;
    }
    
  3. By @Abhitalks is to add a border to your #outer div:

    #outer {
        background-color: red; border: 1px solid gray;
    }
    
Florin Pop
  • 5,105
  • 3
  • 25
  • 58
0

give a border to outer div :

#inner {
    background-color: yellow;    
    margin-left: 80px;
    margin-bottom: 50px;
     
}
#outer {
    background-color: red;
    border:1px solid white;
      
}
<div id="outer">
    <div id="inner">
        test
    </div>
</div>
semirturgay
  • 4,151
  • 3
  • 30
  • 50
-2

This is a Typography concept, generally, vertical margins of adjacent elements collapse!

Have a look at this article

Hitmands
  • 13,491
  • 4
  • 34
  • 69