IE and scrollHeight

I ran into trouble while trying to use JavaScript to set the pixel height of an element to the height of the entire page, including everything outside the viewport. Here’s an example scenario:

A block element on the page:

<div id="some-element"></div>

I want this element to stretch on the fly to the width and height of the entire page. The width is easy, just set the width to 100%:

someElement = document.getElementById('some-element');
someElement.style.position = 'absolute';
someElement.style.top      = '0px';
someElement.style.left     = '0px';
someElement.style.margin   = '0px';
someElement.style.padding  = '0px';
someElement.style.width    = ‘100%’;

The height, on the other hand, turned into a mess. At first I was just setting the height in the same way. Unfortunately, that only covers the currently viewable area. So, if I scroll the page, the effect is broken. I left it that way for a while, figuring it wasn’t a big deal right now.

The issue came up again today, and through a tip from Matt, I started fiddling with scrollHeight and offsetHeight for both the body tag and the html tag. It wasn’t working in Internet Explorer. It was giving the wrong values for both properties. I think it was using the value visible within the viewport. I wrote some debugging alerts:

alert('bodyscroll=' + document.getElementsByTagName('body')[0].scrollHeight);
alert('htmlscroll=' + document.getElementsByTagName('html')[0].scrollHeight);
alert('bodyoffset=' + document.getElementsByTagName('body')[0].offsetHeight);
alert('htmloffset=' + document.getElementsByTagName('html')[0].offsetHeight);

Oddly, IE was returning inconsistent values when the page is scrolled. When the property was accessed while the page was scrolled to the top, the scrollHeight for the body returned 654 pixels, which is wrong. If the page was scrolled down before the property was accessed, the scrollHeight for the body element returned 1134px, which is correct. So we’re getting somewhere. All of the other properties return incorrect values, but at least one of them seems to be halfway working.

The solution came by accident. Later on in the script, I was accessing the body element’s scrollHeight again. It was consistently returning the correct value. So I tried the debugging alerts again, this time with each one doubled:

alert('bodyscroll=' + document.getElementsByTagName('body')[0].scrollHeight);
alert('bodyscroll2=' + document.getElementsByTagName('body')[0].scrollHeight);

alert('htmlscroll=' + document.getElementsByTagName('html')[0].scrollHeight);
alert('htmlscroll2=' + document.getElementsByTagName('html')[0].scrollHeight);

alert('bodyoffset=' + document.getElementsByTagName('body')[0].offsetHeight);
alert('bodyoffset2=' + document.getElementsByTagName('body')[0].offsetHeight);

alert('htmloffset=' + document.getElementsByTagName('html')[0].offsetHeight);
alert('htmloffset2=' + document.getElementsByTagName('html')[0].offsetHeight);

While all of the other properties were still incorrect, the second body scrollHeight alert was consistently returning the correct value. So, here is the solution that worked:

document.getElementsByTagName('body')[0].scrollHeight;
someElement.style.height = document.getElementsByTagName('body')[0].scrollHeight + 'px';

The first call to the scrollHeight property is on it’s own line, and not even used.

Maybe there’s a better way to fix this, and maybe I’m not the first person to come up with this “hack.” But that would be cool if I have found an IE bug and workaround on my own! (Even if it was by accident)

Leave a Reply