I am trying to understand a difference of behavior between Chrome and Firefox. I have published the following CodePen to illustrate the point.
With Firefox, the footer element sticks to the bottom of the wrapper div thanks to the margin-top: -50px
applied on it. This is what I am expecting.
With Chrome (and IE), the margin-bottom
of the p element pushes down the footer, making it overflow. Why is that?
html, body {
margin: 0px;
height: 100%
}
header {
background-color: dodgerblue;
opacity: 0.5;
}
#wrapper {
background-color: tomato;
position: relative;
min-height: 100%;
}
#container p {
background-color: lightgreen;
width: 500px;
/*margin-bottom: 0px;*/
}
footer {
height: 50px;
background-color: dodgerblue;
margin-top: -50px;
opacity: 0.5;
}
<body>
<div id="wrapper">
<header>.</header>
<div id="container">
<p>.</p>
</div>
</div>
<footer></footer>
</body>
Reason
That's because the p
element inside #wrapper
has some margin, which may collapse.
Introduction to margin collapse
The CSS 2.1 spec says
8.3.1 Collapsing margins
In CSS, the adjoining margins of two or more boxes [...] can combine to form a single margin. Margins that combine this way are said to collapse [...]
Adjoining vertical margins collapse [...]
Your styles
Your #wrapper
element has
#wrapper {
height: auto;
min-height: 100%;
}
Old behavior (Firefox)
An old version of the spec said
The bottom margin of an in-flow block-level element with a 'height' of 'auto' and 'min-height' less than the element's used height and 'max-height' greater than the element's used height is adjoining to its last in-flow block-level child's bottom margin if the element has no bottom padding or border.
#wrapper
has height: auto
. However, in case that the window is taller than its contents, min-height
will be the used height (not less). Therefore, margins won't collapse.
This is the behavior observed on Firefox.
New behavior (Chrome)
However, the spec changed, and now the value of min-height
does not matter:
Rephrased the rule for adjoining margins so that the 'min-height' and 'max-height' of an element have no influence over whether the element's bottom margin is adjoining to its last child's bottom margin.
The new rule is
[The] bottom margin of a last in-flow child and [the] bottom margin of its parent [are adjoining] if the parent has 'auto' computed height
Therefore, since height
is auto
, margins should collapse.
This is the behavior observed on Chrome.
Note
Here the current spec seems to imply that min-height: 0
is a requirement:
The above rules imply that the bottom margin of an in-flow block box with a 'height' of 'auto' and a 'min-height' of zero collapses with its last in-flow block-level child's bottom margin [...]
But it is not. The sentence will be clarified in CSS 2.2.
Illustration
The following snippet animates min-height
to illustrate the difference of behaviors between Chrome and Firefox:
min-height
is smaller than content's height,
height
is content's oneheight
is min-height
Therefore, when min-height
reaches content's height, on Firefox there is a sudden (dis)apparition of the space caused by margin collapse.
#wrapper {
background: orange;
margin: 0 1em;
-webkit-animation: animate 1s linear infinite alternate;
animation: animate 1s linear infinite alternate;
}
footer {
background: red;
}
p {
margin: 1em 0;
height: 1.75em;
background: green;
}
@-webkit-keyframes animate {
from { min-height: 4em; }
to { min-height: 6em; }
}
@keyframes animate {
from { min-height: 4em; }
to { min-height: 6em; }
}
/* Content is 4.5em tall */
<div id="wrapper">
<p>Line 1</p>
<p>Line 2</p>
</div>
<footer>Footer</footer>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With