Adjusting the margin-top of a div inside of a container div pushes both the inner div and container div down from body

mikemcg picture mikemcg · Dec 16, 2011 · Viewed 17.4k times · Source

I feel like this must be an issue of me doing something silly, but I can't figure it out. Here's a demo page showing my problem. The source of the page:

<html>
<head>
    <title>demo</title>
    <style type='text/css'>
        body{
            margin: 0px;
            padding: 0px;
        }
        #container{
            height: 100%;
            background-color: black;
        }
        #logo{
            margin: 25px auto auto auto;
            width: 360px;
            height: 45px;
            background-color: goldenrod;
        }
    </style>
</head>
<body>
    <div id='container'>
        <div id='logo'>
            <p>logotext.</p>
        </div>
    </div>
</body>
</html>

So the more you adjust the top value of margin, the further down the page both #logo and #container get dragged. #container should stay put and #logo should be shifting down the page.

Answer

mrtsherman picture mrtsherman · Dec 16, 2011

This is caused by collapsing margins. If two elements have touching margins, then the margins merge. There is a great explanation of this here. Go to the section called Collapsing Margins Between Parent and Child Elements.

Here are three different solutions.

One is to add overflow: auto to the container. This changes the BCF (Block Formatting Context). This technique is described in more detail here.

#container {
    height: 100%;
    background-color: black;
    /* Add oveflow auto to container */
    overflow: auto;
}

http://jsfiddle.net/bzVgV/20/

A second is to use padding on the container instead of a margin on logo. This takes margins out of the equation.

#container {
    height: 100%;
    background-color: black;
    /* Use padding on container instead of margin on logo */
    padding-top: 30px;
}

http://jsfiddle.net/bzVgV/18/

A final solution is to make the margins no longer touch. You can do this by adding a 1px padding to the parent.

#container {
    height: 100%;
    background-color: black;
    /* Now margins of container and logo won't touch */
    padding-top: 1px;
}

http://jsfiddle.net/bzVgV/21/