Peeling Back the Layers
Layer tags get your message across dynamically.
By Aaron Weiss
Until now, Web design using HTML has been as much an exercise in constraints as an experiment in possibilities. There has been no simple way to precisely position elements on a page; once placed, one's elements become quite immobile. The introduction of dynamic HTML, however, in the 4.0 releases of Netscape Navigator and Microsoft Internet Explorer (see "Dynamic HTML: More Power in Your Browser?" June IW), hastens the end of HTML constraints.
In this month's column, we snuggle up to Netscape Navigator's "layers" feature, part of Netscape's breed of dynamic HTML. Layers make it easy to construct complex, precise pages, and some simple JavaScript maneuvers deliver us to that holy grail of the Web: interaction.
Tagging Along
What is a layer? Imagine a hypothetical stack of transparent cellophane sheets. On each sheet you can place any HTML elements you choose. You can color the sheet itself, fill it with a background image, or leave it transparent. Once done, you arrange all of your cellophane sheets in any configuration you like.
The result is a single page made up of several layers. Each layer can be precisely positioned with respect to any other layer; they can be placed above
or below each other and made opaque or transparent. You can hide a layer so that
it is "invisible" until some JavaScript code conjures it up. Layers can even move and rearrange themselves, right in front of the user's eyes.
The layer itself is created with the newly introduced Netscape tag <LAYER>, which is simple to use and perfect for learning to manipulate elements on a Web page. One caveat: This coding is currently
supported only by Netscape 4.0, not Microsoft IE. To create cross-browser-compatible layers, you need to use the somewhat more complex cascading style sheets syntax.
To create a layer, you simply enclose all HTML elements appearing in that layer within <LAYER> tags. The opening <LAYER> tag may contain a variety of attributes that define characteristics of
the layer. Example 1 shows a general template for using <LAYER>, but we will discuss only some of these attributes this month. (Netscape offers comprehensive layer-tag documentation at developer.netscape.com/library/documentation/communicator/layers/index.htm.)
| EXAMPLE 1: GENERAL LAYER TEMPLATE |
<LAYER NAME="layerName" LEFT=xPixels TOP=yPixels
Z_INDEX=zOrder WIDTH=wPixels CLIP="x1,y1,x2,y2"
ABOVE="layerName" BELOW="layerName" VISIBILITY="show|
hide| inherit" BGCOLOR="rgbColor" BACKGROUND="imageURL">
|
We'll use layers to dress up a Web site for the fictional Best Bagels Co. Notice in Screen 1 the positioning of elements in the banner "The Best Bagels in Town." Keep in mind that the banner is not a graphic--it was created using layers. Old-style HTML will not allow you to position "The" and "In Town" as slightly overlapping "Best Bagels," as pictured. Creating this sort of precise positioning with layers is simple, as shown in Example 2.
| EXAMPLE 2: "THE BEST BAGLES IN TOWN" |
<layer name="head1" left=230 top=25 z-index=2>
<font size=7 face="Arial Black"
color="black">Best Bagels</font>
</layer>
<layer name="head2" left=225 top=30 z-index=3>
<font size=2 face="Arial Black" color="white">THE</font>
<layer>
<layer name="head3" left=460 top=66 z-index=3>
<font size=2 face="Arial Balck"
color="white">IN TOWN</font>
|
Using Your Heads
Notice that we have created three layers, named head1, head2, and head3. The first layer contains HTML defining the "Best Bagels" portion of the page. Also keep in mind that the layer is positioned at 230 pixels from the left margin and 25 pixels down from the top margin. The z-index attribute determines overlap order and must contain a positive integer. A layer will appear "above" (that is, overlaid on, as opposed to behind) any layer that has a lower z-index value. So, we chose a z-index value of 2 for the first layer. This allows us to place many layers above it, one layer below it, or both.
The other two layers position their respective HTML elements, both with a z-index of 3, so that they appear above "Best Bagels." Of course, you'll notice that this positioning requires the use of exact pixel placement--quite unlike the relative positioning used in traditional HTML. Thus, it's a good idea to use layer positioning carefully, and keep in mind that the result will look different depending on the user's screen resolution and browser-window
size. In these examples, we're assuming the user has a maximized browser on an 800x600-pixel screen. Creating precisely positioned layers that adapt to varying resolutions and browser sizes is a more of a challenge; when in doubt, keep it simple.
Lights, Camera...
Layers become versatile creatures when combined with the simple potency of JavaScript. In JavaScript 1.2 (supported by Navigator 4.0), the layer object is introduced, which contains a series of properties and methods that allow you to modify, on the fly, any characteristics of a layer, including its position, size, and visibility. The new Layers Array, a property of the document object, provides script access to a particular layer object.
The left and top properties of the layer object provide us with the current position of a layer. By assigning new values to these properties, or using the similar offset() and moveTo() methods, we can relocate the layer to any position on the page.
We can also render a simple scrolling or sliding effect, where a layer moves across the page horizontally. Let's code two functions operating on the Best Bagels Co. example: one that slides "The" and "In Town" inward, and one that slides them outward. We'll tie these functions to the onMouseOver and onMouseOut events for the layer. When you move the mouse pointer over the "Best Bagels" layer, "The" and "In Town" will slide in toward the center of the screen; when you move the mouse pointer off this layer, the words will slide back to their original positions. Example 3 contains our two functions, headin() and headout().
| EXAMPLE 3: THE ELECTRIC SLIDE |
function headin()
{h1x=225;h1y=30;h2x=460;h2y=66;
for (j=0;j<100;j++)
{document.layers["head2"].moveTo(j+h1x,h1y);
document.layers["head3"].moveTo(h2x-j,h2y)
for (x=0;x<300;x++){void(0)}}
}
function headout()
{h1x=225;h1y=30;h2x=460;h2y=66;
for (j=0;j<100;j++)
{document.layers["head2"].moveTo(h1x+100-j,h1y);
document.layers["head3"].moveTo(h2x-100+j,h2y)
for (x=0;x<300;x++){void(0)}}
}
|
Both functions in this example are quite similar. In the first line, we simply set up some variables representing the x and y positions of the two layers we want to slide. We then set up a loop that counts from 0 to 99. For every iteration of the loop, each layer is shifted to a new left position. In this case, we use the moveTo() method of the layer property, although we also could have assigned the new x position to the left property just as effectively. You need only to use the moveTo() method if you want to relocate both the x and y position of the layer simultaneously.
The final line of the loop contains another loop, from 0 to 299, which does nothing--hence the call to void(0). This serves as a brief time delay, giving the appearance of smoothness in the layer sliding. Without this delay, the layer would slide so quickly that it would look herky-jerky.
We also want to tie these functions into event handlers for the first layer, head1. To do this, we need to modify the original <LAYER> tag for that layer. The new tag looks like this:
<LAYER NAME="head1" LEFT=230 TOP=25
Z-INDEX=2 onMouseOver="headin()"
onMouseOut="headout()">.
The Unveiling
Much fun lies in revealing new information. We can do so on our bagel page by displaying only a portion of a layer using the Clip attribute of the <LAYER> tag, and then revealing the hidden portion by using JavaScript to increase the size of the clip, via the clip properties or the resize() method of the layer object.
Let's recode the first layer, as seen in Example 4, so that in addition to "Best Bagels" we also have four hyperlinks. Initially, these links will not appear because we have clipped just below the "Best Bagels" text.
| EXAMPLE 4: HOT BAGEL NEWS |
<layer name="head1" left=230 top=25 z-index=2 clip="400,60"
onMouseOver="headin()" onMouseOut="headout()">
<a href="javascript:void(0)" onClick="showmenu();return
false"><font size=7 face="Arial Black" color="black">Best
Bagels</font>
<br><font face="Arial" color="black">
<a href="recipe.html">Today's Bagel Recipe</a><br>
<a href="history.html">Bagel History</a><br>
false">Daily Specials</a>
<br><a href="order.html">Order Bagels!</a></font>
</layer>
|
As indicated by the onClick event handler added to the "Best Bagels" text, we call a function showmenu() if the user clicks the mouse button on the faux hyperlink, which is represented by assigning javascript:void(0) to the <HREF>: attribute. The function showmenu(), as described below, increases the height of the layer's clip so that the hyperlinks appear:
function showmenu()
{ startx=document.layers["head1"].clip.bottom
for (j=0;j<100;j++)
{ if (menutoggle) {document.layers
["head1"].clip.bottom=startx+j}
else {document.layers["head1"].clip.bot-
tom= startx-j}
for (x=0;x<300;x++) {void(0)} }
menutoggle=!menutoggle
}
The first line in the coding above determines the current y position of the clip size in the head1 layer, via the property clip.bottom. Next, a loop is set up that counts from 0 to 99. After testing the status of menutoggle (which is used to keep track of whether the hyperlink
menu is currently revealed or hidden), a new value is assigned to clip.bottom, either lowering or raising the height of the clip. In this way, when the user clicks on "Best Bagels," the menu will be revealed if hidden, and hidden if revealed.
Altering a layer's clip size to reveal or hide regions is a very useful feature of dynamic HTML. For instance, you can create realistic pull-down menus by creating a graphic image map that looks like a typical pull-down menu. Place this graphic in its own layer, but initially restrict the clip only to the menu title. When the user clicks the menu title, you can then reveal the whole image and it will appear as though the menu has been "pulled down," imitating most computer applications. After the user has made a selection or clicks the menu
title again, you can restrict the clip to hide the menu once more.
Defying The Laws of Physics
"Two objects cannot exist in the same place at the same time," all of us were told in high school science class. Not true with layers!
In both Screen 1 and Screen 2, you may have noticed the "Everyday Special!"
advertisement nestled within the ring of the bagel. In fact, there are two discrete layers within the bagel. One of them, the "Everyday Special!" layer, is visible. The other layer, which contains "Today's Special!" (sesame bagels, 18 for $5.50), is hidden, as Example 5 demonstrates.
| EXAMPLE 5: TWO SPECIALS IN ONE |
<layer name="special1" left=370 top=220
visibility="show" z-index=1>
<font size=4 face="Arial" color="red">
<b>Everyday Special!</b><br><br></font>
<font size=3 face="Arial" color="black">Buy 1 Dozen Bagels,
<br>get 6 free!</font>
</layer>
<layer name="special2" left=370 top=220
visibility="hide" z-index=1>
<font size=4 face="Arial" color="red">
<b>Today's Special!</b><br><br></font>
<font size=3 face="Arial" color="black">18 Sesame Bagels,
<br>only $5.50!</font>
</layer>
|
When the user clicks on the "Today's Special!" hyperlink (assuming that the hyperlink menu is revealed), the function Specials() is called and the promotion appears within the
bagel, as in Screen 3. This function simply reverses the hidden and visible status of the two "special" layers:
function specials()
{document.layers["special2"].visibility="show";
document.layers["special1"].visibility="hide";
}
The Layer Object property visibility can be set to "show" to make the layer visible, or "hide" to make it invisible. You can also set it to "inherit", which would give the layer the same visibility as a parent layer if it were nested within that layer.
Of course, you could have any number of layers residing in the same position and use a loop similar to the one described here to reveal only one layer at a time. This could serve as a form of animation or a sort of rotating-advertisement effect.
You can embed entire pages within a layer, only to keep it hidden until the user clicks a certain navigational tool that slides the new page into the browser window. You can also nest layers within another, so that one layer contains several sublayers.
Layers offer a world of interactive possibilities for your Web pages. In the new wave of Web design, static shouldn't cling to your work.
Aaron Weiss is author of The Complete Idiot's Guide to JavaScript, Second Edition (Que).
Copyright 1997 Mecklermedia Corporation.
All Rights Reserved. Legal Notices.