Monday, 14 May 2012

JavaScript: set image height according to viewport

   


I've recently had to deal with a strange situation in a web project. I basically had an image in the home page which filled roughly the 60 percent of the viewport. The image was responsive and it was adapting to the browser window size. The problem was: the image was resizing following its width and it was not shrinking after a certain point. The result was that when viewed with a 16:9 monitor, the image was somehow too tall to fit the screen and the annoying vertical scrollbar made its appearance (which was meant, for the rest of the pages needed it).
Solution? Well, I decide to use JavaScript and specifically window.innerHeight in order to control the image height according to the viewport.
Before getting into the actual code, I need to explain some things, so bear with me and be patient.

innerHeight and Internet Explorer
We know that we can roughly get the viewport height with window.innerHeight in JavaScript. What you might not know is that Internet Explorer is not really understanding it. If we try to set a variable and assign it the window inner height, the result in IE is a null value. Wow! That is great, isn't it?
In order to avoid the issue in Internet Explorer, we can use document.documentElement.clientHeight. It is clear that we have to deal with two different situations here and treat the resulting values in different ways.

Another thing: min height & max height
When I first tested the resulting JavaScript snippet, I noticed that reducing the viewport to the extreme, my image was shrinking to the extreme. In order to avoid that I decided to determine what was the min height beyond which the image was not resizing anymore. At the same time I decided to determine a max height, because on very large monitor my image was way too big.

The code
The final code is the following function (which I will explain line by line afterwards):
<script type="text/javascript">
    function setImg() {
    if (typeof( window.innerHeight ) == 'number' ) {
      var vpHeight = window.innerHeight;
      var imgHeight = (vpHeight-245);
    } else
    {
      var winHeight = document.documentElement.clientHeight;
      var imgHeight = (winHeight*0.5);
    }
    document.getElementById('myImg').style.width='auto';
    document.getElementById('myImg').style.height=imgHeight+'px';
    document.getElementById('myImg').style.maxHeight='472px';
    document.getElementById('myImg').style.minHeight='150px';    }
</script>
We have then to trigger the function in the body tag. We use the onLoad and onResize events:
<body onload="setImg();" onResize="setImg();">
With the function we first test if window.innerHeight is a number. If so, we are not dealing with IE. We then use window.innerHeight to calculate the image height (imgHeight). In the example I subtract 245, because that's the space used by my header and my footer. You can change that value according to your needs.
The same happens when window.innerHeight is not a number (and thus we are dealing with IE). In my situation I had to multiply the window height by 0.5 (which is like dividing by 2, but that's another story....).
Our image will have an ID="myImg" and we use document.getElementById to style it on the fly. We set the width to auto, the height to imgHeight (the value we found before), and then the min and max heights (the values in the example can be changed according to your personal needs).
As said, place your image in the body section of your page with an ID="myImg":
<img src="images/myImage.jpg" alt="whatever" id="myImg">

And we are done.
The image will resize according to the viewport height in most browsers, and according to the window height in IE.

I hope you like the solution. As usual, share your thoughts, if you like.

5 comments:

Comments are moderated. I apologize if I don't publish comments immediately.

However, I do answer to all the comments.