You are here: irt.org | Articles | Dynamic HTML (DHTML) | Dynamic Positioning [ previous next ]
Published on: Monday 14th September 1998 By: Martin Webb
Web pages are pages of text - or so they were when first introduced. Then Netscape introduced the <IMG> tag, and since then we have been on a slippery slope leading us screaming and kicking into Dynamic HTML (DHTML). DHTML, available in both Netscape Navigator 4 and Microsoft Internet Explorer 4 allows, among other things, the ability for whole parts of a Web page - text and graphics - to move around the screen, disappear, and reappear at will.
In my previous article on DHTML, What is So Dynamic About Dynamic HTML?, we described the main components of DHTML as:
This article will show more DHTML techniques and discuss positioning in more detail.
To create a cross-browser layer (i.e., a layer that works in either NN4 or MSIE4) we can use the style attribute (<... STYLE="position: absolute;" ...>) in conjunction with the DIV or SPAN elements. For example:
Example 1:
<P> <STRONG>This is the first sentence. <SPAN STYLE="position: absolute;"> <FONT COLOR="red">Layer Text</FONT> </SPAN> This is the second sentence.</STRONG> </P>
Click here to see Example 1...
As the layer text is no longer part of the main document no space is reserved for it in the main document, and the main document text is rendered as if the layer did not exist. If you click on the demo button, you'll see that the layer of red text floats above the black text. This is due to the the z-order, i.e., the stacking order of the layers. The layer can be considered to be floating above the main document.
We could repeat the above example using the <DIV> element. The only difference would be that the <DIV> element causes an intial line break to occur. This can be useful, however, depending on the effect you are trying to create.
Example 2:
<P> <STRONG>This is the first sentence. <DIV STYLE="position: absolute;"> <FONT COLOR="red">Layer Text</FONT> </DIV> This is the second sentence.</STONG> </P>
Click here to see Example 2...
Once a layer has broken free from the main document it is possible to adjust the layers properties to move the layer around the screen, to alter the properties to hide the layer, or to change the stacking order of the layers (i.e., place one layer behind another).
As with most technologies on the Internet, things aren't as simple as one would wish. There are two browser vendors Microsoft and Netscape both battling it out to produce the best browser, and trying to get one step ahead of each other. The result: Standards, which often lag behind in this frenzy to get the latest version of the browser released, are not always adhered to.
Before we even attempt to alter the properties of a layer, we must first know which object to modify. Here comes the first hurdle: Microsoft and Netscape use different versions of the Document Object Model (DOM), which are incompatible with each other. Microsoft chose to create an all object and Netscape a layer object.
To address the different DOMs, we must check to see which object is available for us to use. The following JavaScript allows us to do this:
<SCRIPT LANGUAGE="JavaScript"><!-- if (document.all) { // MSIE4+ } else if (document.layers) { // NN4+ } else { // not a version 4 or greater browser } //--></SCRIPT>
To address a layer property we then use either of the following two hiearachical syntax:
document.all(layerIdentify).propertyName
or:
document.layers[layerIdentify].propertyName
Where propertyName is the name of the property you wish to gain access to, and layerIdentity is the identity of the layer itself. For example, the layer <SPAN ID="myLayer">This is my layer</SPAN> is identified as myLayer.
View the source code for Example 3...
Click here to see Example 3...
Example 3 is an effective technique for finding out the properties and property values of a layer for yourself. The code demonstrates the use of the for/in loop, in this instance looping around all the properties of the layer identified as myLayer:
Suffice to say, there are not many (if any) properties with identical names. The layer objects even have nested objects. In NN4, we have: clip, window, layers and parentLayer. Meanwhile, MSIE4 uses: all, children, document, filters, offsetParent, parentElement, parentTextEdit and style.
Some of these objects are self-explanatory (e.g., window, layers, all, and document). One or two require closer examination. clip holds the clipping properties of the layer, while style holds the Cascading Style Sheet (CSS) properties of the layer. We can now draw up a compatability table for for like properties:
NN4+ | MSIE4+ | Description |
---|---|---|
clip.left | style.clip | The left edge of the clipping rectangle (the part of the layer that is visible.) |
clip.top | style.clip | The top edge of the clipping rectangle (the part of the layer that is visible.) |
clip.right | style.clip | The right edge of the clipping rectangle (the part of the layer that is visible.) |
clip.bottom | style.clip | The bottom edge of the clipping rectangle (the part of the layer that is visible.) |
id | id | The layer identifier |
left | posLeft | The horizontal position of the layer's left edge, in pixels, relative to the origin of its parent layer. |
top | posTop | The vertical position of the layer's top edge, in pixels, relative to the origin of its parent layer. |
pageX | left | The horizontal position of the layer, in pixels, relative to the page. |
pageY | top | The vertical position of the layer, in pixels, relative to the page. |
visibility | style.visibility | Whether or not the layer is visible -- visible|hidden |
zIndex | style.zIndex | The relative z-order of this layer with respect to its siblings. |
bgColor | style.backgroundColor | The color to use as a solid background color for the layer's canvas. |
Developers are constantly striving to create pages that work in as many browsers as possible -- so I won't bore you with versions that only work on NN4 or only on MSIE4. I'll try and show solutions that work on both at once and fail gracefully on others.
One thing to be aware of is that NN4 Cascading Style Sheet (CSS) support can be disabled independently of JavaScript. It is possible to discover that the layer object you are intending to manipulate is not present. Therefore always check the existence of the object before attempting to access its properties. This can easily be achieved by testing whether the object reference is equal to null. For example: if (document.layers[layerId] != null). In this case, the layer is present, so it can be manipulated.
View the source code for Example 4...
Click here to see Example 4...
Example 4 illustrates an effective "tooltips" working example. When the mouse pointer is moved over the link text, a hidden layer suddenly becomes visible. When the mouse moves off the link, the layer disappears again. It may at first look extremely complicated, but it is a generic solution that can be used many times throughout the same document.
Each "tooltip" is initially created following the link text that it is associated with (in this example as a table with a bright background to obscure any text behind the layer). If the browser does not support CSS or if CSS support is disabled, the "tooltip" text would be visible right away. For CSS-enabled browsers, the "tooltip" text would be converted into invisible layers by initially setting CSS visibility property to hidden, and the CSS position property to absolute for all myStyle class references.
It is possible to place a layer anywhere within the current document -- this can either be an absolute or a relative placement. The placing of layers can be achieved using CSS style attributes:
Example 5:
<SPAN ID="myLayer" STYLE="position:absolute; top:0; left:0;"> <IMG SRC="sphere.gif" WIDTH="43" HEIGHT="43"> </SPAN>
Example 6:
<SPAN ID="myLayer" STYLE="position:absolute; top:50; left:50;"> <IMG SRC="sphere.gif" WIDTH="43" HEIGHT="43"> </SPAN>
Click here to see Example 5...
Click here to see Example 6...
View the source code for Example 7...
Click here to see Example 7...
View the source code for Example 8...
Click here to see Example 8...
Click here to see Example 9...
The code for Example 5 places the sphere image in the top left corner of the current document. But the code for Example 6 offsets the image from the top left-hand corner by 50 pixels in both the x and y axis.
Once a layer has been placed on the page it can be repositioned elsewhere with JavaScript by using the left and top layer properties in NN4 and the style.posLeft and style.posTop layer properties in IE4. Example 7 positions the sphere image relative to its previous position.
Example 7 works fairly well, as the initial starting position when the layer is known (e.g., top:50; left:50;). However, there is a slight problem in IE4 when trying to place layers relative to their current position when the current position is not known.
For example, the Example 8 does not specify top and left positions in the CSS style attributes. When altering the placement of the image, NN4 works correctly, but IE4 doesn't. The reason being is that in IE4 the initial values of style.posLeft and style.posTop are set to zero. Any addition or subtraction results in the layer being positioned relative to the top left-hand corner of the screen rather than its initial starting position.
In NN4, Example 8 works as expected by placing the layers to the right of the links and aligned with the top of the first link, whereas in MSIE4 the layers are positioned 60 pixels above the start of the document, and thus do not show correctly.
The solution? Always place the layer in an absoulte position (e.g., top:50; left:50;), and then move it relative to its last known position. By making the following two changes to Example 8, we can produce a script that works the same in both NN4 and MSIE4 (see Example 9 below):
Example 9:
<STYLE TYPE="text/css"><!-- .myStyle { position: absolute; visibility: hidden; top: 0; left: 0; } //--></STYLE>
and:
<SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript"><!-- reposition('text1',100,10); reposition('text2',100,10); reposition('text3',100,10); //--></SCRIPT>
We are now getting to the interesting part of DHTML - movement - something not possible in previous browser versions, but now possible in NN4 and MSIE4. Once a layer has been positioned within the document it can be positioned again and again, ad nauseum. As with anything that moves or blinks on the screen, it's best to use it sparingly, as moving objects can detract from the rest of the page, and can annoy your visitors.
View the source code for Example 10...
Click here to see Example 10...
Example 10 demonstrates a ball bouncing inside a box. Apart from a bit of math, the example only makes use of what we have learned thus far. The example has two layers box and sphere, both of which are positioned 50 pixels from the top and left-hand sides of the main document. The layers are independent of one another (i.e., there has been no attempt made to place one layer inside another -- although this is possible). Because the box layer was defined before the sphere layer, it appears beneath the sphere layer, (i.e., the zIndex of the box layer is less than that of the sphere layer).
The example makes use of a timer to repeatedly call the moveit() function, which calculates the next position of the sphere layer and then repositions it.
In Example 10, we saw a demonstration of how the zIndex is generated when creating layers -- the first layer is defined as the lowest zIndex and appears at the bottom of the pile of layers. We can, however, manipulate the zIndex to shuffle the order of the images in the document, bringing layers to the top, or pushing layers to the bottom, or anywhere in between.
View the source code for Example 11...
Click here to see Example 11...
Example 11 is an amended version of the bouncing ball demo -- it defines three layers box1, box2 and sphere. As before the zIndex is implicit, so sphere appears above box2 which appears above box1. But in this example, one of the first things we do after repositioning the layers is alter the zIndex properties in NN4 and the style.zIndex properties in MSIE4 to change the zIndex order of the three layers. This places box2 above sphere which is above box1. The higher the zIndex value, the higher it appears in the main document.
The ball then bounces above the box1, but below the box2, layer. The stripe effect is achieved by placing a table with alternating colored columns. Those with a background color obscure the bouncing ball; those without a background color are effectively transparent. The form button, when clicked, invokes the swp() function which changes the order of the box1 and box2 layers.
Note: Microsoft Internet Explorer on the Mac does NOT support clipping.
The clipping region defines the part of the layer that is visible. Any part of the layer that is outside the clipping region is transparent. A clipping region is defined with the use of four attributes that make up the shape of a rectangle: top, right, bottom and left. Again, NN4 and MSIE4 implement these in totally different manners.
View the source code for Example 12...
Click here to see Example 12...
Example 12 demonstrates a simple clipping example you can use toexperiment with this clipping rectangle. NN4 has a clip object for each layer, which has four properties: clip.top, clip.right, clip.bottom and clip.left. MSIE4, on the other hand, has only one clip property: style.clip for each layer. However, style.clip has a string value that represents the four clip values. For example, style.clip = 'rect(top right bottom left)'.
This may seem complicated at first, but it only requires string concatenation to turn integer values into the required clipping string. For example, the following code will create a clipping rectangle in the top right-hand corner of the layer that's 50 pixels wide and 100 pixels deep.
style.clip = 'rect(' + 0 + ' ' + 50 + ' ' + 100 + ' ' 0 + ')';
In this article, I have shown you how to position layers, how to hide and reveal layers, and how to move the layers in the x, y and z directions. With these abilities dynamic Web pages can come to life. Before you get too carried away with your creations -- think about whether your page needs to be dynamic, and for how long. You may find that your visitors do not appreciate the effects the same way you do. However, a little bit of Dynamic HTML used in the appropriate places can offer an attractive alternative to a static Web page.
A Gift of "Life" : The Document Object Model
Multimedia in Microsoft Internet Explorer
What is So Dynamic About Dynamic HTML?