Reputation: 7369
I've encountered this problem before and have not really found a solution. I have this html (simplified):
<div class="outer">
<header>my header section</header>
<div id="body">
<h1>Page H1</h1>
<p class="content"></p>
</div>
<footer>footer section</footer>
</div>
And I'm trying to get the actual height of #body (using jQuery) like this:
var b = $('#body').outerHeight(true);
But that is not returning what I think is the correct height. The height I expect is the height that FireFox also reports in the "Box Model" (in Developer Tools). But jQuery is returning a different value, which appears to exclude the top margin of the h1 tag.
I also tried to use innerHeight of #body but it returns the same value. Anyone has an idea of how to do it, hopefully without having to iterate through the child elements?
I have this fiddle for your reference.
Upvotes: 2
Views: 1566
Reputation: 17701
This may be due to a box model feature known as 'collapsing margins'. Individually, these elements should return their proper calculated heights, but when margins collapse as stacked, the result may account for your discrepancy.
Here's an excellent article describing the scenario: http://reference.sitepoint.com/css/collapsingmargins
In simple terms, this definition indicates that when the vertical margins of two elements are touching, only the margin of the element with the largest margin value will be honored, while the margin of the element with the smaller margin value will be collapsed to zero.
This behavior is best demonstrated with a short example. Consider the following code:
h1 {
margin: 0;
background: #cff;
}
div {
margin: 40px 0 25px 0;
background: #cfc;
}
p {
margin: 20px 0 0 0;
background: #cf9;
}
<h1>Heading Content</h1>
<div>
<p>Paragraph content</p>
</div>
Further info can be found at the W3C Box Model spec: http://www.w3.org/TR/CSS21/box.html#collapsing-margins
When two or more margins collapse, the resulting margin width is the maximum of the collapsing margins' widths. In the case of negative margins, the maximum of the absolute values of the negative adjoining margins is deducted from the maximum of the positive adjoining margins. If there are no positive margins, the maximum of the absolute values of the adjoining margins is deducted from zero.
Upvotes: 4
Reputation: 7369
@Stuart's answer explains the height 'anomaly', if I can call it that. Thanks to @Stuart. His answer led me to look for a solution for that scenario.
Here's an SO item which mentions a hack, which appears to work on IE8, Chrome and FF. And it addresses my need. Here's my updated fiddle for anyone interested. Basically, I had to change the way I calculate the height as follows (and remove the wrapping afterwards):
var b = $('div#body').wrap('<div style="border:1px solid transparent;"></div>' ).parent().height();
$('div#body').unwrap();
Upvotes: 0