Window size and scrolling
Finding the size of the browser window
- Clue browser can only work out window width.
- Tkhtml Hv3 has the body/documentElement clientHeight/Width values reversed - versions before September 2007 also do not support innerHeight/Width, so they cannot work with this script.
There are some constants available that give the document area of the window that is available for writing to. These will not be available until after the document has loaded and the method used for referencing them is browser specific. The available constants are:
- window.innerHeight/Width
- Provided by most browsers, but not Internet Explorer 8-, and even in Internet Explorer 9+, it is not available in quirks mode.
- document.body.clientHeight/Width
- Provided by many browsers, including Internet Explorer.
- document.documentElement.clientHeight/Width
- Provided by most DOM browsers, including Internet Explorer.
This is a little messy because the clientHeight/Width properties can mean different things in different browsers, and even different things in the same browser, depending on whether the document type declaration triggers the browser's strict mode or quirks mode. In some cases, they refer to the dimensions of the window, and sometimes they refer to the dimensions of the contents of the document. The table below shows what the properties mean in different browsers, and different modes:
Browser | window. innerHeight |
document. body. clientHeight |
document. documentElement. clientHeight |
---|---|---|---|
Opera 9.5+ strict | window | document | window |
Opera 9.5+ quirks | window | window | document |
Opera 7-9.2 | window | window | document |
Opera 6 | window | window | N/A |
Mozilla strict | window | document | window |
Mozilla quirks | window | window | document |
Newer KHTML | window | document | window |
Older KHTML | window | document | document |
Chrome/Safari 4+ | window | document | window |
Safari 3- | window | document | document |
iCab 3 | window | document | document |
iCab 2 | window | window | N/A |
IE 9+ strict | window | document | window |
IE 6-8 strict | N/A | document | window |
IE 5+ quirks | N/A | window | 0 |
IE 4 | N/A | window | N/A |
ICEbrowser | window | window | document |
Tkhtml Hv3 | window | window | document |
Netscape 4 | window | N/A | N/A |
As you can see, the browsers seem to have settled on at least one reliable property; innerHeight. Internet Explorer took a long time to make up its mind, and its influence means that other browsers change their clientHeight behaviour in different versions in order to match it. For now, almost all browsers provide window.innerHeight/Width so that can be used. The other values may swap the values around when the browsers are in strict/quirks mode. Fortunately, the only browser that does not provide innerHeight, Internet Explorer 8- (and 9+ in quirks mode), gives 0 in quirks mode for the root element's clientHeight. This means that if we see a value on the documentElement's properties, and the browser does not provide the properties on the window object, we can assume it is Internet Explorer 6-8 in strict mode.
The most accurate method I could come up with uses the following algorithm:
- If window.innerHeight/Width is provided, that is fully trustworthy, use that (Hooray!).
- Else if document.documentElement.clientHeight/Width is provided and either one is greater than 0, use that.
- Else use document.body.clientHeight/Width.
This algorithm will fail with IE 6-8 in 'standards compliant mode' and all versions in quirks mode if the window is shrunk to 0px by 0px. This is only possible when the user actively shrinks the window to hide the page within it. Even then, it will just give the height of the document instead, so it should not be a problem. The following code performs the algorithm as described.
function alertSize() {
var myWidth = 0, myHeight = 0;
if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
window.alert( 'Width = ' + myWidth );
window.alert( 'Height = ' + myHeight );
}
Test it here: get the inner dimensions of this window.
Note that browsers may take the width either inside or outside the scrollbar (if there is one). In most current browsers, you can ensure that your page triggers standards mode, then use documentElement.clientHeight to get the height inside any scrollbar. window.innerHeight can be used to get the height outside any scrollbar, but that is not possible in Internet Explorer 8-. It is a little messy, and if you do need to make the distinction, you will need to decide which browsers are likely to be important. If you need to reliably get the dimensions inside the scrollbar, including in all current browsers (not IE 6-), you can create a fixed position element with top, right, bottom and left all set to 0, and measure its offsetHeight and offsetWidth.
Finding how far the window has been scrolled
- OmniWeb 4.2-, NetFront 3.3- and Clue browser do not provide any way to do this.
- Safari and OmniWeb 4.5+ have bugs that do not affect this script - see below.
When trying to produce document effects like falling snow, or more serious things like menus that remain in the same place relative to the browser window when the user scrolls, it is essential to be able to obtain the scrolling offsets in both the horizontal and vertical direction.
There are also three ways to find this out, but it is easier than finding the size of the window. Most browsers provide window.pageXOffset/pageYOffset. These are completely reliable. Once again, Internet Explorer 8- (and 9+ in quirks mode) is the odd one out, as it does not provide these properties. Internet Explorer and some other browsers will provide document.body.scrollLeft/Top. In strict mode, IE 6+ and a few other browsers, provide document.documentElement.scrollLeft/Top.
If the scrollLeft/Top properties are provided on either the document.body or document.documentElement, they are reliable in everything except older Safari and OmniWeb 4.5+, which return -8 if the scrolling is 0, but get all other scrolling offsets correct. However, as they correctly provide window.pageXOffset/pageYOffset, this script will not have any problems.
The following script will obtain the scrolling offsets.
function getScrollXY() {
var scrOfX = 0, scrOfY = 0;
if( typeof( window.pageYOffset ) == 'number' ) {
//Netscape compliant
scrOfY = window.pageYOffset;
scrOfX = window.pageXOffset;
} else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
//DOM compliant
scrOfY = document.body.scrollTop;
scrOfX = document.body.scrollLeft;
} else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
//IE6 standards compliant mode
scrOfY = document.documentElement.scrollTop;
scrOfX = document.documentElement.scrollLeft;
}
return [ scrOfX, scrOfY ];
}
Test it here: get the scrolling offsets.
Last modified: 19 March 2011