Six months ago

target="_blank" title="To Dr. Unclear's Netscape 6 tests">a reader of my site alerted me to an important bit of data: when using

a doctype that switches Explorer 6 to Compatibility Mode, several properties of

document.body are reassigned to document.documentElement. This

information enabled me to get

target="_blank" title="Sticky Menu script">one of my scripts

working in Explorer 6 with a doctype.

At first I thought that all properties of document.body were

reassigned to document.documentElement, but this turned out not to be the case.

Because the data confused me and because I had other things to do, I only

skimmed through the W3C Recommendations and Flanagan's "JavaScript, the Definitive Guide"

to get a theoretical overview. I postponed the necessary browser tests, because they were

likely to be complex and time-consuming.

Theory

The overall picture that emerged was as follows:

Netscape 6, Explorer 5 and Konqueror have adopted documentElement as part

of their W3C DOM support. body was originally Explorer-only, but more recently

both Netscape 6 and Opera 6 have started supporting it (Konqueror not tested).

So documentElement refers to the outermost box in a document, the HTML element,

while body refers to its only child box: the BODY element. Through their properties

we can read out information about the two most important elements.

--------------

HTML

------------

BODY

------------

--------------

Unfortunately my tests have proven this theoretical model to be unfounded when applied

to properties like clientWidth and offsetHeight.

Besides there is a third box that needs to be measured: the browser window itself. It is frequently

far smaller than the HTML document it contains. The theoretical model described above doesn't leave

any room for the window dimensions; nonetheless they are present.

No standards

What we want is to read out interesting information about the entire HTML page and the browser

window. One of the problems is that the properties that contain this information are not standardized.

In the W3C DOM, to read out the total height of the HTML document you'd have to do

document.defaultView.getComputedStyle(document.documentElement,null).getPropertyValue("height")

Apart from the syntax being way too complicated, this only works in Mozilla. It's even worse

if you want to know the window width and height or the scrolling offset: there is no official

W3C way to read out this information. (Should there be one? At the moment I don't

think so. But feel free to disagree.)

Fortunately the browser vendors have created their own properties: Netscape 4 and up supports window.innerWidth/Height

and Explorer 4 and up supports document.body.clientWidth/Height. All this works fine, though without

the blessing of W3C.

Doctype switching

When Explorer 6 added the possibility of entering strict standards compliance mode by using

title="To the MSDN explanation of doctype switching. This link works at the moment of writing, but no doubt in a few months this page wil lhave been moved"

target="_blank">certain doctypes
, it turned out that using these doctypes also influenced

the value of some of these properties. As far as I know this happens only in Explorer 6 on Windows, I haven't

yet found a trace of doctype-switching effects on JavaScript properties

in Mozilla and Explorer on Mac. (But I stand ready to be corrected)

So what exactly happens? I wondered for six months, then finally found the time to do some browser

tests.

The experiment

So I set up an experiment. I researched four property pairs, all of which may be properties of

document.body and document.documentElement. The pairs are:

  1. clientWidth, clientHeight
  2. offsetWidth, offsetHeight
  3. scrollWidth, scrollHeight
  4. scrollTop, scrollLeft

I created two test pages which print out the values of these properties. They are exactly the

same, except that I added the doctype

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">

to one of them. It causes Explorer 6 to enter compatibility mode.

I chose this doctype more or less randomly. For the moment I assume that all doctypes in Microsoft's

list cause the same compatibility mode. (Here, too, I stand ready to be

corrected in case anyone has noticed a difference).

View the test pages for yourself, if you like.

I tested the various properties in several browsers: Explorer 5.0 and 6.0 on Windows, Explorer

5.0 on Mac OS 9 and 5.1 on OS X, and Mozilla 1.0 final. I also studied Opera 6, which doesn't

support documentElement at all.

There were no differences between both

Mac Explorers, only very slight differences between the Windows Explorers on the no-doctype page.

The actual testing consisted of carefully measuring the various widths and heights and finding

out which properties contained these numbers.

No general rules

I'd hoped to find some general rules for dealing with document.body,

document.documentElement and doctype switching. Unfortunately the conclusion must be

that there are considerable differences between body and documentElement

and that a lot happens in Explorer 6 when switching between quirks and standards mode,

but that it is impossible to formulate a general theory.

See the target="_blank">table of research results and try to make sense of it. I can't. If you

do find a general rule, please note it in a comment below.

One rule concerning Explorer 6 in Strict mode has been made clear by Michael van Ouwekerk of

13th Parallel. He wrote:

From what I've gathered so far, IE6 in Strict mode always makes the html

element as big as the viewport. The styles given by currentStyle are width:

auto, height: auto, overflow: scroll. The offsetWidth and offsetHeight are

always equal to the viewport's width and height. When there is a lot of

content, the overflow: scroll takes care of that.

This seems to explain the values I found, so I think he's right.

A few more interesting points:

Practice

So how do you write cross-browser scripts that avoid all these complications?

Here are some examples that survive using a doctype that switches Explorer 6 to compatibility

mode:

Scrolling offset

The scrolling offset of the page is reflected in document.body.scrollTop/Left,

except when you use a doctype in Explorer 6, then it is reflected in

document.documentElement.scrollTop/Left. Opera is unreliable here. Fortunately the

old Netscape properties window.pageXOffset/pageYOffset still work in all Netscapes

and Opera. So the script would become:

if (window.pageYOffset)

{

pos = window.pageYOffset

}

else if (document.documentElement && document.documentElement.scrollTop)

{

pos = document.documentElement.scrollTop

}

else if (document.body)

{

pos = document.body.scrollTop

}

and pos contains the vertical scrolling offset.

Window dimensions

The window dimensions are reflected in document.body.clientWidth/Height,

except when you use a doctype in Explorer 6, then they are reflected in

document.documentElement.clientWidth/Height. Opera is unreliable here, the window

height is never less than the height of the HTML document. Fortunately the

old Netscape properties window.innerWidth/Height still work in all Netscapes

and Opera. So the script would become:

if (window.innerWidth)

{

theWidth = window.innerWidth

}

else if (document.documentElement && document.documentElement.clientWidth)

{

theWidth = document.documentElement.clientWidth

}

else if (document.body)

{

theWidth = document.body.clientWidth

}

and theWidth contains the width of the window. Note that the clientWidth is always

the width excluding the scrollbars. Generally (but not always),

offsetWidth/Height gives access to the window width including the scrollbars.

Conclusion

The conclusion must be that the implementation of the body/documentElement

properties in the various browsers, with and without doctypes, is very complicated. I can find no overall

theoretical model that explains what the four property pairs are for and what the effect of a

doctype switch is.

I hope my target="_blank">table of research results will allow people to formulate theories. If you think you understand the behaviour of a certain browser (or, better yet, all browsers), please leave a comment below.