Dynamic HTML: The Definitive Reference, 2rd Ed.Dynamic HTML: The Definitive ReferenceSearch this book

9.2. About client- and offset- Properties

In Internet Explorer 4, Microsoft introduced a set of size and position properties for elements that render as part of the regular body content (i.e., not positioned via CSS). These properties had the potential to assist scripts in their tasks of determining locations and dimensions of body content so that positioned elements could be moved in relation to these fixed elements. The properties are:

clientHeight clientLeft clientTop clientWidth
offsetHeight offsetLeft offsetTop offsetWidth

The sad news is that between buggy behavior under fairly common circumstances in IE/Windows, and a different philosophy behind their implementation in IE/Mac, these properties can be difficult to work with. Add to this mix the fact that Microsoft tried to mend the errors for IE 6 by altering the playing field when the DOCTYPE element puts the browser into "standards compliant" mode (and fixing the genuine measurement bugs while in that mode). If that weren't enough, Netscape 6 and later implements some of these non-W3C properties for the convenience of DHTML authors, but does so in a way that comes closer to the old IE/Windows mode (minus the measurement bugs) than to the IE 6 standards compliant mode. Confusing? You bet!

The primary measurement discrepancies among browsers and compatibility modes have to do with element padding (if any is applied) and the positioning context for the element (even for nonpositioned elements). The number of permutations of oddities introduced by element and style sheet combinations boggles the mind, so I'll take one example of a common task—using a script to place the content of a CSS-positioned element directly atop the content of an inline element—to demonstrate the range of possible problem areas with a variety of browsers and compatibility modes. Because the properties described in this section are not part of the W3C DOM (as of Level 2), it is difficult to say which approach is "correct." It's more a question of how to use these properties to accomplish your desired tasks on your target browsers.

For this scenario, the following tag was inserted into an arbitrary place within a document so that its precise location would vary with browser, window size, and other environmental conditions:

<img id="fixedImg" src="bkgnd.jpg" alt="Locator box" height="90" 
     width="120" style="padding:2px; border:3px solid green; margin:5px">

I use an image here because its content is the same size regardless of browser, and will let us see how the various size properties report the element's overall or content size (i.e., we're not at the mercy of font rendering vaguaries). Including padding, border, and margin settings for this fixed element will illustrate that some of these style attributes can impact topographical information about the element in the document. Table 9-1 shows the values for relevant size and position properties for several browsers and compatibility modes.

Table 9-1. Comparative property values (pixels) for a 120-by-90 pixel inline element

Property name

IE 4 Windows

IE 6 Windows (old mode)

IE 6 Windows (standards mode)

IE 5 Mac

NN 6.2

clientLeft 3 3 3 247[12]

n/a

clientTop 3 3 3

377[12]

n/a

offsetLeft 237 242 232 237 217
offsetTop 377 382 367 362 383
clientWidth 120 120 124 120

n/a

clientHeight 90 90 94 90

n/a

offsetWidth 126 126 130 130 130
offsetHeight 96 96 100 100 100
naturalWidth

n/a

n/a

n/a

n/a

120
naturalHeight

n/a

n/a

n/a

n/a

90
width 120 120 124 120 120
height 90 90 94 90 90
offsetParent.clientLeft 2 2 0 0

n/a

offsetParent.clientTop 2 2 0 0

n/a

offsetParent.offsetLeft 0 0 10 0 0
offsetParent.offsetTop 0 0 15 0 0

[12]For inline text elements in IE/Mac, add a margin of offsetParent to offset property values to get the equivalent of client properties.

Table 9-1 reveals a great deal about how various browsers report the location and size of an inline element. Some of the precise numbers, such as the location coordinates, are not critical measures because each browser renders surrounding content slightly differently, and any scripts that rely on the position will read the live values in each case. But several very important details are worth noting for this particular element insertion:

To gain an appreciation for why these differences can be important to your DHTML scripting, consider what it takes to position a second img element that has no padding, border, or margin so that the top-left corner of the positioned image is precisely at the top-left corner of the static image content. Depending on the browser and compatibility mode, you must take into account a variety of measurement components of the fixed element to accumulate a value to assign to the movable element's style.left and style.top properties. Table 9-2 shows the pieces required for the style.left property for several browser classes. The corresponding top values would also be assigned to the movable element's style.top property.

Table 9-2. Sample position components

 

IE Windows (old mode)

IE 6 Windows (standards mode)

IE 5 Mac

NN 6

fixedElem.offsetLeft

 

fixedElem.offsetParent.offsetLeft  

   
fixedElem.style.padding  

 

fixedElem.style.borderWidth

 

fixedElem.clientLeft    

 

Bear in mind that the style object properties in use here are string values that include units. This means that scripts must perform type conversions to do the math. For example, the IE 6/Windows standards mode assignment statement would be as follows:

positionedElem.style.left = fixedElem.offsetLeft + 
  fixedElem.offsetParent.offsetLeft + parseInt(fixedElem.style.padding) + 
  parseInt(fixedElem.style.borderWidth) + "px";

This syntax also assumes that the style object has the style sheet properties handy because they were set as an attribute of the element. If the style sheet is defined elsewhere in the page, you'll have to go the extra step of reading the effective style applied to the element (see DOM-specific techniques for this in Chapter 5). One more factor to take into account is the offsetParent location. If the element whose location you're reading is nested within multiple positioning contexts, you should use a separate function to accumulate all offsetLeft values of offsetParent s out to the root element. On the plus side, you can use the same calculation for Netscape 6 because the offsetParent.offsetLeft property returns zero, so its addition won't affect the outcome, even for nested positioning contexts.

For IE 5/Mac, the clientLeft and clientTop properties are valid for only some elements, such as inline img and positioned elements. For other kinds of elements, you need to calculate the equivalent of the clientLeft and clientTop properties by including the margins of the body element, which have significant default values you must account for as follows:

positionedElem.style.left = fixedElem.offsetLeft +
  parseInt(fixedElem.offsetParent.currentStyle.marginLeft)  + "px";

Netscape 7 adds support for the IE clientHeight and clientWidth properties (not clientLeft or clientTop), but only for elements that display scrollbars due to content overflowing the viewable area. This includes the document.body element, when it is larger than the content region of the browser window. For nonscrolled elements, both property values are zero.

This digression serves as an advisory that the client and offset properties are both helpful and tricky. Almost any task is possible, but it may require much trial, error, and cross-browser testing to achieve the desired results with your combination of elements. Not every positioning task is quite so difficult (as in the flying objects example in Chapter 4). But don't be surprised if a complex element design and precision positioning task across the domains of fixed elements, positioned elements, and event coordinates takes hard work to accomplish.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.