MerickOWA
MerickOWA

Reputation: 7612

Strange extra spacing between header and body when extra element is added

I have the following HTML

<body>
    <header></header>
    <h2>Title</h2>
</body>

With the following CSS

html {
    height: 100%;
}

body {
    height: 100%;
    margin: 0;
}

header {
    float: left;
    background: black;
    height: 100%;
    width: 150px;
}

http://jsfiddle.net/ZqeED/1/

IE10, Chrome 26, and Firefox 20 all show unwanted extra space at the top, as well as a scroll bar.

Removing the h2 element causes this space to disappear.

My question is, what is going on? Is there an HTML layout rule which explains why the space is being added?

Upvotes: 4

Views: 11788

Answers (3)

Adrift
Adrift

Reputation: 59859

Thats one of the stranger cases of margin collapsing - two block-level elements vertical margins will always collapse in the normal flow. Those two elements in this case are the <body> and the <h2>. If you take the <h2> out of the normal flow (float, absolutely position) or change its display to inline-block you'll see that the margins will not collapse and will be "respected" by the <body>

http://jsfiddle.net/ZqeED/2/

From the 2.1 Spec:

"If the element's margins are collapsed with its parent's top margin, the top border edge of the box is defined to be the same as the parent's."

This explains why the top margin on the <h2> is adding the gap on the <body> - as said before if you were to float, absolutely position or change to display: inline-block; the <h2> top margin edge will be the same as the parents border edge and the "gap" would disappear:

http://jsfiddle.net/ZqeED/4/

Upvotes: 8

animuson
animuson

Reputation: 54787

This is caused by your <header> element being displayed as a floated element. By default, a block-level element expands horizontally to fill the entire parent container, and also extends back behind any floated content.

Your block-level <h2> element actually starts clear at the 0,0 point in the top left of the screen and from there gets its default margin-top applied to it to push the text down. Your floated <header> element then starts down from that margin to be inline with the new text position, as seen below:

Inspecting the element's dimensions

An easy way to get around this is to use padding instead of margins (if you need the space above the <h2> but not above everything). See a jsFiddle example.

Upvotes: 1

What have you tried
What have you tried

Reputation: 11148

This issue is reffered to as collapsing margins

To fix, add:

 h2
 {
     padding: 0;
     margin: 0;
 }

And the problem is gone.

Another solution would be to add float: left or display: inline-block to the h2

Working Fiddle

Upvotes: 1

Related Questions