Tuesday 19 March 2013

A naturally placed DIV that responsively expands to browser window/viewport height

Have you ever seen those web applications that have a pane on the left hand side and a main body and somehow it fits it all into the size of your browser window (viewport) what ever browser/device you use or screen size you have and it doesn't show your browser's scroll bars? I'm talking about the height of the left pane and the body adjusting automatically to the height of your browser window.

Have you ever tried searching for how they do it? I tried and couldn't find a straight answer. I'm no javascript nerd so I had to figure this out the hard way with trial and error. To save any of you some time here is my solution using a little CSS and some responsive javascript (jQuery):

Scenario:

I have a typical page with a banner at the top and a navigation bar just below it, and I want my web application-style left pane and main body pane to fit into the vertical white space of the page body that is not already occupied by the banner or navigation bar. My HTML looks a little like this:

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css.css">
<script src="jquery.js"></script>
<script src="js.js"></script>
</head>
<body>
<div id="container">

<div id="banner"></div>
<div id="nav"></div>

<div id="webapp">
  <div id="leftpane"></div>
  <div id="mainbody"></div>
</div>

</div>
</body>
</html>

So, for this example, my main concern is the #leftpane div. If you understand the code for that, you can duplicate the approach for the #mainbody. (To be honest, I'm writing this post here before I tackle mainbody next)

The CSS for leftpane is:

#leftpane{
  margin:0 auto;
  float:left;
  border:1px solid darkgreen;
  background-color:rgba(0, 0, 150, .15);
  vertical-align:top;

  width:30%;
  overflow-y:auto;
}

Notice there is no mention of position:absolute. That's because this example is NOT about filling the page from top to bottom with the left pane. If you want that kind of information, then google will easily find you that. Instead, what we are doing here is having the top of the div element be in its normal position, while the bottom border of the div will expand vertically depending on the size of the window/viewport. I only care about the height of the div in my example. Widths are managed with width: n% and using min-width:n px, but I will not discuss widths any further.

Anyway. How do we get the leftpane to expand according to size of the window? With a bit of Javascript (jQuery). The  javascript below is responsive. When the page first loads it calls the snapLeftpane() function and resizes the leftpane and then if the user makes their window bigger or smaller, it calls the snapLeftpane() function again to resize the leftpane again.

But I set some limits. If the window becomes too small, like if the user is messing about and makes their browser window too small, then it snaps the leftpane to the minimum height allowable. And in the opposite situation, when the user has a huge window, it limits the height of the leftpane to the maximum height allowable, so the web app doesn't look ridiculously disproportioned.

Here's the javascript:

function snapLeftpane(){
    var minHeight = 450,
        maxHeight = 800,
        wHeight = $(window).height();
    var el = $('#leftpane');
    if(el.length){
        var top = el.offset().top + 5;
    if(wHeight
>=  minHeight && wHeight <= maxHeight) {
        el.height((wHeight - top) + "px");
        console.log('naturally expanding height ' + el.height());
    } else if (wHeight
> maxHeight) {
        el.height(maxHeight + "px");
        console.log('set to max height ' + el.height());
    } else if (wHeight
< minHeight) {
        el.height(minHeight + "px");
        console.log('set to min height ' + el.height());
    }

    }
}

$(window).on('resize load', function(){snapLeftpane();});


And if you run this code in your browser and play around with the size of the browser window, you will see how it adjusts the height of the left pane accordingly or snaps it to the minimum height or maximum height if you make the window too small or too large. I recommend you modify the min and max heights to your preferences.

That's it. Hope this helps :)