Ghost Top Body Margin With Floated Divs

2019-07-12 17:46发布

问题:

I wrote the following code and tried placing three left floated divs in a father containing div. For some reason, the body tag seems to have a ghost top margin, which is a property not defined in my code. However, if I remove the margin-bottom property of the containing div or apply a clearfix style to it, the top margin is gone. What causes the ghost top margin and how to fix it? Thx!

Check the screenshots below:

  • Original code:

  • Margin-bottom removed:

    • Clearfix style applied:

This the original code:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <style>
            html {
                font: 16px/2 Tohoma, Verdana, Arial, Sans-serif, 'Microsoft YaHei';
                background: #ccc;
            }

            body {
                margin: 0;
                padding: 0;
            }

            .clear-fix:after {
                content: '';
                display: block;
                clear: both;
            }

            #wrap {
                margin: 0 auto;
                width: 1000px;
                min-height: 800px;
                background: #fff;
            }

            #header {
                margin-bottom: 20px;
            }

            .first, .second, .third {
                float: left;
                padding: 20px;
                min-height: 100px;
            }

            .first {
                background: gray;
            }

            .second {
                background: blue;
            }

            .third {
                background: yellow;
            }
        </style>
        <title>
            Another Web Page
        </title>
    </head>
    <body>
        <div id="wrap">
            <div id="header">
                <div class="first">This is the first floating division</div>
                <div class="second">This is the second floating division</div>
                <div class="third">This is the third floating division</div>
            </div>
        </div>
    </body>
</html>

Original code preview:http://jsfiddle.net/qv8ph0gw/

回答1:

The explanation:

There are a few things occurring here.

When elements are absolutely positioned or floated (as in your case), they are removed from the normal flow of the document. Here is relevant documentation confirming this:

9 Visual formatting model - 9.5 Floats

Since a float is not in the flow, non-positioned block boxes created before and after the float box flow vertically as if the float did not exist. However, the current and subsequent line boxes created next to the float are shortened as necessary to make room for the margin box of the float.

In your case, the children elements of the #header element are floated. Since all of the children elements are floated, the #header element essentially collapses upon it self since it doesn't have any dimensions.

Here is a visual example. As you can see, the parent, #header element, has a height of 0:

Since the element has a height of 0, the margin-bottom essentially acts as a margin-top, and the margin collapses with the body element.

I just answered a question about collapsing margins here, but here is the relevant documentation:

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.

Possible solutions/workarounds:

As you noted, the problem is resolved my adding a clearfix to the #header element. The clearfix essentially prevents the parent element from collapsing upon itself, which means that the bottom margin do not collapse.

You could achieve the exact same thing by simply adding overflow: hidden to the element:

Example Here

#header {
  margin-bottom: 20px;
  overflow: hidden;
}


回答2:

Can you try after removing below style?

body {
  margin: 0;
  padding: 0;
}