L84
L84

Reputation: 46318

Use JS to Calculate Div Height

I am using some javascript to calculate the height of the page and then set a min-height on on a div. The reason for this is to push the footer to the bottom of the page for pages that are short on content. My issue is the min-height is about 30-40 px to big thus causing scroll bars. (Note: I am not using a solution like sticky footer for various reasons and prefer this solution.)

Here is my code:

JS

$(function() {
  var height = $(window).height() - ($("header").outerHeight() + $("footer").outerHeight() );
 $("#page-content").css("min-height",height+"px");
});

HTML

 <header class="container">
 <div id="menu" class="row">
   <!-- Content -->
 </div>
</header>

<div id="page-content">
  <!-- Content --> 
</div>

<footer>
  <!-- Content --> 
</footer>

I believe the issue lies in my CSS. For example I have a margin in the header as so:

#menu{
 margin: 5px auto 10px;
}

If I remove that code it will reduce the scrollbar just a little bit. (I have other margins set in place on the page so changing just this one will not work as a solution).

How would I re-write the JS code to factor in the margin for the header and other sections?

Upvotes: 1

Views: 5574

Answers (5)

L84
L84

Reputation: 46318

For some reason the JS is not calculating the margins. I added the margins I had in the header and footer and they totaled 45px. Thus the script now looks like so:

$(function() {
  var height = $(window).height() - ($("header").outerHeight() + 
               $("footer").outerHeight() + 45   ); 
  $("#page-content").css("min-height",height+"px"); 
});

I add 45px and the script now functions correctly.

Upvotes: 1

chbrown
chbrown

Reputation: 12026

The <header> box's height doesn't reflect the child #menu's margins because they are both normal box elements, and if the #page-content had margins, they would overlap the #menu's margins, in which case the header's height would include some part of the content's height, which wouldn't make sense.

The issue is collapsing margins: http://www.w3.org/TR/css3-box/#collapsing-margins

As that page explains, you can get tell the browser not to collapse margins a few ways:

  • add display: inline-block; to your #menu { } rules (my first suggestion)
  • add overflow: hidden; to your header { } (a potentially better suggestion if you're having alignment issues)
  • make your <header> absolutely positioned, or float it. Or do that to the #menu inside.

Or if you want to go for a hack, you could calculate the header height manually:

var header_height = $("header").outerHeight() +
   parseInt($("header").children().css('margin-top'), 10) +
   parseInt($("header").children().css('margin-bottom'), 10);

Now that I think about it, this makes sense, and I think the css spec is doing the right thing.

Updated: http://jsfiddle.net/HzBSz/2/

Also see: Outer element margin not equal to inner element margin

Upvotes: 1

brightboy2004
brightboy2004

Reputation: 268

Try .outerHeight(true) for all your elements instead of .height() or .outerHeight():

$(function() {
  var height = $(window).outerHeight(true) - ($("header").outerHeight(true) + $("footer").outerHeight(true) );
 $("#page-content").css("min-height",height+"px");
});

.height() - returns the height of element excludes padding, border and margin.

.innerHeight() - returns the height of element includes padding but excludes border and margin.

.outerHeight() - returns the height of the div including border but excludes margin.

.outerHeight(true) - returns the height of the div including margin.

Upvotes: 0

Stupidfrog
Stupidfrog

Reputation: 2102

Perhaps you look at this http://matthewjamestaylor.com/blog/keeping-footers-at-the-bottom-of-the-page may solve your problem.

Upvotes: 0

Aehmlo
Aehmlo

Reputation: 930

Why not just place the footer on the bottom manually? I mean, I know you said you prefer not to, but why? If you want it to always be there, do

position:relative;
bottom:0;

If you want it to scroll with the rest of the page (as it sounds like you may), use

position:absolute;

instead. This is a much better method than dynamically inserting dummy content to push a footer down.

Upvotes: 0

Related Questions