Skip to page content or Skip to Accesskey List.

Work

Main Page Content

Document Body Doctype Switching And More

Rated 3.68 (Ratings: 6)

Want more?

  • More articles in Code
 
Picture of ppk

Peter-Paul Koch

Member info

User since: 12 Sep 1999

Articles written: 8

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:

  • document.documentElement has been

    target="_blank">standardized by W3C as a kind of shortcut to the HTML element, the

    highest element in the DOM tree of any (X)HTML page. W3C has not defined any properties

    for this element.
  • document.body has been added by Microsoft. Originally it was a convenience

    object that had several properties with information about the current state of the browser

    window and the document in it. Microsoft defined lots of properties, the most important of

    which are clientWidth and clientHeight which store the current

    size of the browser window. It also has properties

    like document.body.text, accessing the old TEXT attribute. It thus (also) refers

    to the BODY element.

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:

  • Above I said document.body is supposed to represent the BODY element, while

    document.documentElement should represent the HTML element. This turned out only to be

    the case with the offset properties in Mozilla and the scrollWidth/Height properties

    in Explorer 6 in standards compliance mode. Otherwise this theory has little to do with practice.
  • Explorer 5 on Mac and Opera 6 are inconsistent in their use of the offset properties. While

    offsetHeight gives the height of the entire HTML document (as it does in most

    other browsers), offsetWidth gives the width of the window, not of the

    HTML document.
  • The only reliable property pair is scrollTop/Left: it always gives the amount

    of pixels the page has scrolled. Unfortunately this information is highly doctype-sensitive:

    in standards compliance mode in Explorer 6 these properties belong to documentElement,

    while in quirks mode they belong to body, just like in all other browsers. In Explorer 5.0

    on Windows these properties were assigned to both body and documentElement.

    I wish Explorer 6 had done the same regardless of doctype, it would spare me the need to rewrite

    scripts.
  • I have been unable to find out what function the scrollLeft/Top property pair

    has in Opera 6. The values simply don't make sense.

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.

Peter-Paul Koch is a freelance browser expert and JavaScript guru living in Amsterdam, the Netherlands. He has been an Internet professional only since 1998, so he's definitely second generation.

His personal site is www.quirksmode.org. It includes the W3C DOM Compatibility Tables, currently the best resource on the Internet for this subject. Because of this research, he has been asked to co-edited chapters 17 to 19 of Flanagan's "JavaScript, the Definitive Guide", O'Reilly, 4th edition.

He is an administrator of the WDF-DOM mailing list, that counts most international JavaScript gurus among its members.

He has written the "Keep it Simple" column on Digital Web Magazine, as well as articles on A List Apart, Apple Developer Connection, and O'Reilly's Web Dev Center, in addition to Evolt.

The access keys for this page are: ALT (Control on a Mac) plus:

evolt.org Evolt.org is an all-volunteer resource for web developers made up of a discussion list, a browser archive, and member-submitted articles. This article is the property of its author, please do not redistribute or use elsewhere without checking with the author.