Categories
JavaScript

Adding Persistence to DHTML Effects

Originally published at Netscape Enterprise Developer, now archived at the Wayback Machine

Dynamic HTML (DHTML), implemented in Netscape Navigator 4.x and Microsoft Internet Explorer 4.x, gives the Web page visitor the ability to alter the position, format, or visibility of an HTML element. However, the effects that are created with DHTML are transitory in that the next time the page is refreshed, the current DHTML state is not maintained and the page opens showing the same content layout as when the page is first loaded. Any changes to the content based on DHTML are not maintained. Sometimes this isn’t a problem, but other times this is irritating to the reader. This article covers how to add persistence to a DHTML page. Examples should work with all forms of Netscape Navigator 4.x and Internet Explorer 4.x, but have only been tested with IE 4.x and Netscape Navigator 4.04 in Windows 95.With DHTML, developers can provide functionality that hides or shows whichever layer the Web page reader wants to view. Developers can also add functionality that lets readers move content. The problem is that DHTML effects are not session persistent, which means that they aren’t maintained between page reloads. Following a link to another site and returning to the page can trigger a reload, which wipes out the effect and annoys the user,. especially if he or she has spent considerable effort achieving the current DHTML state.

For example, you can use DHTML to let your reader position your page contents for maximum visibility in her browser and get the page look just right. If she decides to leave your site to check Yahoo’s news for a few minutes and then comes back, her settings will have been erased.

So, what’s the solution to these problems? It’s relatively simple — add document persistence using Netscape-style cookies.

Using cookies 
Despite the name, you won’t find Netscape-style cookies at your local bakery. Cookies are bits of information in the form of name-value pairs that are stored on the client’s machine for a set period of time or until the browser is closed. For security, cookies are created and accessed using specific syntax, are limited to 300 cookies total within the cookie database at 4K per cookie, and are limited to 20 cookies per domain (the URL where cookie was set).

Cookie syntax consists of a string with URL characters encoded, and may include an expiration date in the format:

Wdy, DD-Mon-YY HH:MM:SS GMT

Netscape has a complete writeup on cookies (see our Resource section at the end), including functions that can be copied and used to set and get cookies. I created modified versions of these functions to support my DHTML effects. As I don’t want to add to overly burdened cookie files, I don’t set the expiration date, which means the cookie does not get stored in the persistent cookie database or file. This also means that the DHTML effect only lasts for the browser session. However, this fits my needs of maintaining a persistent DHTML state in those cases where the reader moves to another site or hits the reload button.

DHTML state cookie functions
I created a JavaScript source code file called cookies.js that has two functions. One function sets the cookie by assigning the value to the document.cookie object. More than one cookie can be set in this manner, as cookie storage is not destructive — setting another cookie does not overwrite existing cookies, it only adds to the existing cookie storage for the URL. The cookie setting function is shown in the following code block:

// Set cookie name/value
//
function set_cookie(name, value) {
   document.cookie = name + "=" + escape(value);
}

Next, the function to get the cookie accesses the document.cookie object and checks for a cookie with a given name. If found, the value associated with the cookie name is returned, otherwise an empty string is returned. The code for this function is:

// Get cookie given name
//
function get_cookie(Name) {
  var search = Name + "="
  var returnvalue = "";
  if (document.cookie.length > 0) {
    offset = document.cookie.indexOf(search)
    if (offset != -1) { // if cookie exists
      offset += search.length
      // set index of beginning of value
      end = document.cookie.indexOf(";", offset);
      // set index of end of cookie value
      if (end == -1)
         end = document.cookie.length;
      returnvalue=unescape(document.cookie.substring(offset, end))
      }
   }
  return returnvalue;
}

That’s it to set and get cookie values. The next section shows how to create two Web pages with simple, cross-browser DHTML effects. Then each page is modified to include the use of cookies to maintain DHTML state.

_BREAK1 Creating the DHTML Web pages
To demonstrate how to add persistence to DHTML pages, I created two Web pages implementing simple DHTML effects. The first page layers content and then hides and shows the layers based on Web-page reader mouse clicks. The second page has a form with two fields, one for setting an element’s top position and one for setting an element’s left position. Changing the value in either field and clicking an associated button changes the position of a specific HTML element.

Adding DHTML persistence for layered content
For the first demonstration page, a style sheet was added to the top of the page that defines positioning for all DIV blocks, formatting for an H1 header nested within a DIV block, and three named style sheet classes. The complete style sheet is shown here:

<STYLE type="text/css">
        DIV { position:absolute; left: 50; top: 100; width: 600 }
        DIV H1 { font-size: 48pt; font-family: Arial }
        .layer1 { color: blue }
        .layer2 { color: red }
        .layer3 { color: green }
</STYLE>

Next, three DIV blocks are used to enclose three layers, each given the same position within the Web page. Each block also contains a header (H1), with each header given a different style-sheet style class. The HTML for these objects is:

<DIV id="layer1">
<H1 class="layer1">LAYER--BLUE</H1>
</DIV>
<DIV id="layer2" style="visibility:hidden">
<H1 class="layer2">LAYER--RED</H1>
</DIV>
<DIV id="layer3" style="visibility:hidden">
<H1 class="layer3">LAYER--GREEN</H1>
</DIV>

That’s it for the page contents. To animate the page, I created a JavaScript block that contains a global variable and two functions. The global variable maintains the number of the layer currently visible. The first function is called cycle_layer; this function determines which layer is to be hidden and which is shown next, and then calls a function that performs the DHTML effect:

<SCRIPT language="javascript1.2">
<!--

// current layer counter
current_layer = 1;

// assign document clicks to function pointer
document.onclick = cycle_layer;

// cycle through layers
function cycle_layer() {
   var next_layer;
   if (current_layer == 3)
        next_layer = 1;
   else
        next_layer = current_layer + 1;
   switch_layers(current_layer, next_layer);
   current_layer = next_layer;
}

The scripting block also assigns the function cycle_layer as the event handler function for all mouse clicks that occur within the document page. By doing this, clicking any where in the page document area that doesn’t include any other content results in a call to the function to change the layer.

The switch_layers function is the DHTML effects function, and it uses the most uncomplicated technique to handle cross-browser differences: it checks for browser type and then runs code specific to the browser. Other techniques can be used to handle cross-browser differences, but these are outside of the scope of this article. All that the function does is hide the current layer and show the next layer in the cycle, as shown here:

// hide old layer, show new
function switch_layers(oldlayer, newlayer) {
   if (navigator.appName == "Microsoft Internet Explorer") {
        document.all.item("layer" + oldlayer).style.visibility="hidden";

        document.all.item("layer" +
newlayer).style.visibility="inherit";
        }
   else {
        document.layers["layer" + oldlayer].visibility="hidden";
        document.layers["layer" + newlayer].visibility="inherit";
        }
}

Try out the first sample page. Clicking on the document background, not the text, changes the layer. Try setting the layer to the green or red layer, accessing another site using the same browser window, and returning to the sample page. When you return, the page is reset to the beginning DHTML effect, showing the blue layer.

To correct the loss of the DHTML effect, we can add persistence to the page by storing which layer is showing when the page unloads. This information is captured in a function called when the onUnLoad event fires.

To add persistence, I added the cookies Javascript source code file to the page, using an external source code reference:

<!-- add in cookie functions -->
<SCRIPT language="javascript" src="cookie.js">
</SCRIPT>

Next, I added the function to capture the DHTML state:

// onunload event handler, capture "state" of page (article)
function capture_state() {
   set_cookie("current_layer",current_layer);
}

When the page reloads, the onLoad event is fired, and a function is called from this event to “redraw” the DHTML effect. The function is called start_page, and it pulls in the cookie containing which layer should be shown:

function start_page() {
// get cookie, if any, and restore DHTML state
  current_layer = get_cookie("current_layer");
  if (current_layer == "")
        current_layer = 1;
  else
        switch_layers(1, current_layer);
}

Finally, the two event handlers, onUnLoad and onLoad, are added to the BODY HTML tag:

<BODY onload="start_page()" onunload="capture_state()">

You can try out the second sample page, which has DHTML persistence — again, change the layer, open some other site and then return to the sample page. This time, the DHTML effect persists during a page reload.

Sometimes an effect requires more than one cookie, as the next example demonstrates.

_BREAK2 Adding DHTML Persistence for Positioned Content
In the next example, I used a style sheet again to define CSS1 and CSS-P formatting for the DIV block that is going to be moved in the page:

<STYLE type="text/css">
        DIV { position:absolute; left: 50; top: 100; width: 600 }
        DIV H1 { font-size: 48pt; font-family: Arial }
        .layer1 { color: blue }
</STYLE>

Next, I created a form that has two text elements and associated buttons. One text and button element pair is used to change the DIV block’s top position, one pair is used to change the DIV block’s left position. The entire form is shown here:

<DIV id="first" style="position:absolute; left: 10; top: 10; z-index:2">
<form name="form1">
Set new Left Value: <input type="text" name="newx" value="50">
<input type="button" onclick="newleft(newx.value)" value="Set New
Left"><p>
Set new Top Value: <input type="text" name="newy" value="100">
<input type="button" onclick="newtop(newy.value)" value="Set New Top">
</form>
</DIV>

Next, the positioned DIV block is created:

<DIV id="layer1" style="z-index: 1">
<H1 class="layer1">LAYER--BLUE</H1>
</DIV>

Once the page contents have been created, you can add code to animate the DIV block based on whether the top or left position is changed. The function to change the top position is:

// change top value
function newtop(newvalue) {
   if (navigator.appName == "Microsoft Internet Explorer")
        layer1.style.pixelTop = parseInt(newvalue);
   else
        document.layer1.top = newvalue;
}

Again, the least complex technique to handle cross-browser differences is used, which is to check for the browser being used and run the appropriate code. The function to change the left position is identical to the top position function, except the CSS-P attribute “left” is changed rather than the CSS-P attribute “top”:

// change left value
function newleft(newvalue) {
   if (navigator.appName == "Microsoft Internet Explorer")
        layer1.style.pixelLeft = parseInt(newvalue);
   else
        document.layer1.left = newvalue;
}

That’s it for this page. You can try it out on the third sample page, where you can change the position of the DIV block by changing the left position, the top position, or both. Again, open another site in the browser and then return to the example page. Notice how the position of the DIV block does not persist between page reloadings.

Adding persistence to this page is very similar to adding persistence to the layered example page, except two values are maintained: the top and left values. The start_page and capture_state functions for this DHMTL effect are:

function start_page() {
// get cookie, if any, and restore DHTML state
  var tmpleft;
  tmpleft = get_cookie("currentleft");
  if (tmpleft != "") {
        currentleft = parseInt(tmpleft);
        currenttop = parseInt(get_cookie("currenttop"));
        newtop(currenttop);
        newleft(currentleft);
        if (navigator.appName == "Microsoft Internet Explorer") {
           document.forms[0].newx.value=currentleft;
           document.forms[0].newy.value=currenttop;
           }
        else {
           document.first.document.forms[0].newx.value = currentleft;
           document.first.document.forms[0].newy.value = currenttop;
           }
        }
}

function capture_state() {
        set_cookie("currentleft", currentleft);
        set_cookie("currenttop", currenttop);
}

To see how it works, try out the fourth sample page, move the DIV block, open another Web site in the browser and return to the example page. This time the DHTML effect does persist between page reloadings.

Summing up
In a nutshell, the steps to add persistence to a page are:

  1. Create the DHTML page
  2. Determine the values that must be maintained to re-create an existing effect
  3. Add the Netscape-style functions to the page
  4. Capture the onUnLoad event and call a function to capture the DHTML effect persistence values
  5. Capture the onLoad event and call a function to restore the DHTML effect from the persisted values

Using Netscape-style cookies to maintain DHTML effects won’t help with some DHTML persistence problems. For example, DHTML effects can be lost when a page is resized. In addition, if a page is resized between the time the DHTML persistence values are stored and the page is reloaded, the values may no longer work well with current page dimensions. However, for most effects and for most uses, the use of Netscape-style cookies is a terrific approach to DHTML persistence.

Categories
JavaScript

A cross-browser text rollover

You may or may not have seen image rollovers. Rollovers are effects that provide visual feedback to the reader when his or her mouse is over an item. Well, you can also create text rollovers. This cheap page trick shows just one technique that you can use to create a text rollover.

First, I create a page with two menu items. Each menu item consists of two different layers, created using DIV blocks. One set of layers contains the original menu text, and the “highlighted” text that shows when the reader’s mouse is over the text. I created a style sheet then that has a style setting for the “normal” text and one for the “highlighted” text:

<STYLE type="text/css">
	BODY { background-color: white }
	DIV { position: absolute }
      .highlight { text-decoration: none; font-size: 12pt; font-family: 
			Arial; font-weight: bold; color: green }
      .normal { text-decoration: none; font-size: 10pt; color: black }
</STYLE>

Next, I create two menu items and each item’s associated highlighted text. As Navigator does not currently generate mouse events that can be captured on general DIV blocks, at least general DIV blocks, I enclose the text within links (“A”), and assign the styles to the A tags:

<BODY>

<!-- menu item one -->
<DIV id="one" style="postion:absolute; left: 150; top: 150">
<a href="" class="normal" onclick="return false" onmouseover="switch_state('one','oneb')">
Menu Item One
</a>
</DIV>
<DIV id="oneb" style="postion:absolute; left: 150; top: 150; visibility:hidden">
<a href="" class="highlight" onclick="return false" onmouseout="switch_state('oneb','one')">
Menu Item One
</a>
</DIV>

<!-- menu item two -->
<DIV id="two" style="postion:absolute; left: 150; top: 180">
<a href="" class="normal" onclick="return false" onmouseover="switch_state('two','twob')">
Menu Item Two
</a>
</DIV>
<DIV id="twob" style="postion:absolute; left: 150; top: 180; visibility:hidden">
<a href="" class="highlight" onclick="return false" onmouseout="switch_state('twob','two')">
Menu Item Two
</a>
</DIV>

Notice that the onmouseover event is trapped and handled for the “normal” text, but the onmouseout event is handled for the highlighted text. Each event handler calls one function, switch_state, and passes to this function which object is hidden and which is shown. The order that the objects are passed is different based on which event and for which object.

Next, I created two functions, switch_state and SetObjectVisibility. If I had used the cross-browser objects (see the DHTML section for these), I wouldn’t need the SetObjectVisibility function. The switch_state object does nothing more than hide and show the appropriate text block.

That’s it for this Cheap Page Trick. Try it out for yourself. What’s the cost for the trick? Less than 1K. Now, that’s Cheap!

Categories
Web

YASD Code Byte presents: Relative and Absolute Positioning – Part II Tables

Note: Navigator 4.x and up and IE 4.x and up

Prior to Navigator 4.x and Internet Explorer 4.x, one of the most commonly used HTML elements was the HTML table. With tables, you could position content in the middle of a page, create columns of data, position images.

With the introduction of CSS-P tables are not the only method used to position content, but they are still being used. Why is this? One main reason is that tables are still the best technique to use for positioning content for older browsers, and they are still one of the better techniques to use when it comes to “flowing” content into a specific section of a page, not just a single section of the page.

The best of all worlds might be the ability to use CSS-P with tables, but this is easier said then done. This second part to relative and absolute positioning demonstrates the ins and the outs of using CSS-P with tables.

First up, one thing a person might think of doing is using a table to position all content, and then use CSS-P to position content within the table. So, I created two tables, each with a text block enclosed within DIV blocks. Both DIV blocks are positioned relative to the enclosing table cell, with one set to a relative position of (0,0), and the second set to a relative position of (50,50). The code for the page is:

<table width=90% border=3>
<tr><td>
<DIV style="position:relative; color: blue">
Relative, 0, 0, Parent is table
</DIV>
</td></tr>
</table>	
<p>
<table width=90% border=3>
<tr><td>
<DIV style="position:relative; left: 50; top: 50; color: red">
Relative, 50, 50, Parent is table
</DIV>
</td></tr>
</table>

You can see the surprising results of using relative positioning within a table by checking out the page. Notice that both text blocks are positioned relative to the tables they are enclosed within, but also notice that the relative positioning of the second DIV block actually moved it “outsite” the table parameters.

I decided to try something else. This time, I positioned the table within a DIV block that has been absolutely positioned, set the width and height of the table’s cell using CSS1, and then used relative positioning with a DIV block contained IN the table. The code for this is:

<DIV style="position:absolute; left: 50; top: 150">
<table width=90% border=3>
<tr><td style="width:90%; height:100">
<DIV style="position:relative; left: 50; top: 50; color: lime">
Relative, 50, 50, Parent is table
</DIV>
</td></tr></table>
</DIV>

Well, interesting results here, as you can see by looking at the page and results that differ between Navigator and IE. For IE, the contents are positioned relative to the table, and the table height is set to 100 pixels in height a width of 90% page size. However, the height style attribute is not used within Navigator, and additionally, the font style applied to all DIV blocks is not applied to the inner DIV block. The latter happens because the DIV block style is applied to all DIV blocks at the document level, and the inner DIV block is now contained within a table which is contained within another DIV block. The only style that is applied to the inner block is the one applied as an inline style.

What other damage can I do? Well I created an absolutely positioned DIV block containing a table containing another absolutely positioned DIV block, and the results are even more interesting as you can see from the new page. What happened with this example, for both IE and Navigator, is that absolute positioning of an element removes the element’s height and width considerations when other content is placed on the page. Since the table is picking up its height from its contents, and the contents themselves are not participating in normal page layout, you get a squished table row. The table is wide enough only because its width has been set using the old style “width” attribute:

<DIV style="position:absolute; left: 50; top: 50">
<table width=90% border=3>
<tr><td >
<DIV style="position:absolute; left: 50; top: 50; color: magenta">
absolute, 50, 50, Parent is table
</DIV>
</td></tr></table>
</DIV>

Wait, wait! I’m not done twisting this one around. What happens if I remove the width attribute of the table. Take a look at the results with this page. Now, this is really interesing. First, for Navigator the contents do show, with a little bitty table above and to the left. However, try the page with IE 4.x. The contents don’t show either, but they do if you click the bottom scroll bar to move the page to the left a wee bit. The results are really strange, and note that I am using IE 4.01 on Windows 95 when I get them.

I have a little trick for handling sizing of tables when the contents are absolutely positioned, and I wrote about an article about this trick for Netscape Enterprise Developer’s February issue. What I do is use a transparent 1-pixel GIF placed into the table, and set to the size I want the table cell to occupy. If I want the cell to be 200 x 200, I set the image’s width and height to 200 each, as can be seen from the next example. The code to create this is:

<table border=3>
<tr><td >
<img src="blank.gif" height=200 width=200>
<DIV style="position:absolute; left: 50; top: 50; color: firebrick">
absolute, 50, 50, Parent is table
</DIV>
</td></tr></table>

Note also that IE wraps the contents to fit the table cell, but Navigator doesn’t. To get both to wrap, the DIV block should be set to the same width as the cell, adding for positioning to the left. In this case the width is set to 150, 50 for the left positioning and 150 to make a cell width of 200.

Want to see some other techniques? Well, try the page from the following code, which sets up the table separate from the table contents and uses the transparent GIF to size the table:

<table border=3 cols=4 width=400>
<tr>
<td >
<img src="blank.gif" height=100 width=100>
</td>
<td >
<img src="blank.gif" height=100 width=100>
</td>
<td >
<img src="blank.gif" height=100 width=100>
</td>
<td >
<img src="blank.gif" height=100 width=100>
</td>
</tr>
</table>

<DIV class=fonts style="position:absolute; left: 20; top: 20; width: 100; color: firebrick">
absolute, 20, 20, Parent is table
</DIV>
<DIV class=fonts style="position:absolute; left: 130; top: 20; width: 100; color: gray">
absolute, 20, 20, Parent is table
</DIV>
<DIV class=fonts style="position:absolute; left: 235; top: 20; width: 100; color: navy">
absolute, 20, 20, Parent is table
</DIV>
<DIV class=fonts style="position:absolute; left: 340; top: 20; width: 100; color: goldenrod">
absolute, 20, 20, Parent is table
</DIV>

Another page shows the results of a table with individually positioned DIV blocks, and using the transparent GIF to size and space the table cells. The results are actually pretty good, and the code for this effect is:

<table  cols=4 >
<tr>
<td height=100 width=100>
<DIV style="position: absolute; left: 0; top: 0; width: 100">
<img src="blank.gif" height=100 width=100 align=top>
</DIV>
<DIV class=fonts style="position:absolute; left: 20; top: 20; width: 100; color: firebrick">
Cell One
</DIV>
</td>
<td height=100 width=100>
<DIV style="position: absolute; left: 110; top: 0; width: 100">
<img src="blank.gif" height=100 width=100 align=top>
</DIV>
<DIV class=fonts style="position:absolute; left: 130; top: 20; width: 100; color: gray">
Cell Two
</DIV>
</td>
<td height=100 width=100>
<DIV style="position: absolute; left: 215; top: 0; width: 100">
<img src="blank.gif" height=100 width=100>
</DIV>
<DIV class=fonts style="position:absolute; left: 235; top: 20; width: 100; color: navy">
Cell Three
</DIV>
</td>
<td height=100 width=100>
<DIV style="position: absolute; left: 320; top: 0; width: 100">
<img src="blank.gif" height=100 width=100>
</DIV>
<DIV class=fonts style="position:absolute; left: 340; top: 20; width: 100; color: goldenrod">
Cell Four
</DIV>
</td>
</tr>
</table>

Best of all with this effect, is that the table itself can be included within an absolutely positioned DIV block, positioning the entire contents, as shown in the next example page. However, view this page with Navigator and the table is not positioned. Big Heavy Sigh.

One thing I was able to get working, with both browser, and in a way I actually planned (gasp), was the example shown in this Page. In this, I created a table with two images that are positioned using DIV blocks. The positioning is relative, and I set the top position of the second image to a negative value so it would overlap the first image. The code to create this effect is:

<table width=50% border=3 align=center>
<tr><td>
<DIV style="position:relative;top: 100; left: 40%">
<img src="yasd.gif">
</DIV>
<DIV style="position:relative; left: 40%; top: -30">
<img src="yasd.gif">
</DIV>
</td></tr></table>

Notice the white space around the images? That’s because the table height is equal to the height of the two images as they are positioned in page layout terms one after the other. The use of the negative top value makes no difference with page layout, the rest of the HTML content, including the table, “sees” these two images as layered one after the other, hence the row height.

And I think that’s a good place to stop…with an example that works the way I expect, and I even know the reason why.

That’s it for Part II of absolute and relative positioning.

Categories
Technology

Using Old Page layout tricks with new technology

Originally published at Netscape Enterprise Developer, now archived at the Wayback Machine

Prior to the release of Netscape Navigator 4.0 and Microsoft Internet Explorer 4.0, Web developers had to use a lot of tricks to control the layout and looks of a Web page. There was no easy way to control the positioning of elements on the page — the two photos that lined up perfectly over the text on your browser when you laid out your page could be completely askew when someone else downloaded them.

To counteract this non-standard display problem, Web authors tended to develop an arsenal of “tricks” that made layout easier. Among the more common tricks were the use of HTML tables to control page layout and a one-pixel transparent GIF to control the placement of content within a line or within a page.

With the newer 4.0 browsers, however, site developers have new, fewer roundabout techniques to control element placement and page layout. For instance, the Cascading Style Sheet Positioning (CSS-P) specification (now incorporated into the CSS2 working effort) and the original CSS1 specification add layout capabilities to HTML development. (See the page listed in our Resources section below for detailed Cascading Style Sheet information.) In addition, the rise of dynamic HTML technology means that authors not only have control of the static placement of HTML elements on a page, they can also move elements and hide or show them after a page is displayed.

Even with these new techniques, however, I find myself using old standbys — specifically, HTML tables and the one-pixel transparent GIF — but now I’m using them in combination with the new technologies to create interesting and useful effects. You too can combine the best of the old and new for more control over your page layout.

The one-pixel transparent GIF

Prior to the release of Navigator 4.0 and IE 4.0 and the development of the Cascading Style Sheet Positioning spec, Web page authors were severely limited in how much we could control the placement of Web page elements. One element that you could use to provide some placement control was the image element, defined with the <IMG> tag. Using the image element, an author could specify a vspace or hspace (vertical or horizontal spacing) value, as well as a vertical or horizontal alignment (right or left, top or bottom).

In addition to the image element, some older browsers supported the use of the transparent GIF. Using a transparent GIF, the specific color you identify within the image is transparent when loaded into a browser.

David Seigal of Killer Web Site fame combined the two ideas and came up with the image element that happened to be a small one-pixel transparent GIF. Since it’s tiny and transparent, it can be easily added to a layout without disrupting the underlying content; by using the specific spacing value capability of the image element on the one-pixel transparent GIF, you could add white space or position content in a specific location.

Beginning with Navigator 4.0 and followed by Internet Explorer 4.0, however, Web authors began using CSS-P for specific element positioning and CSS1 for adding margins or padding to a page (or even within an element). There was no longer a need for the little one-pixel transparent GIF. But an odd thing happened when I was about ready to delete my trusty little GIF file: I actually found a new use for it.

I wanted to create a page for my Dynamic Earth Web site that showed several different minerals and included a moveable “frame” that positioned itself over each image based on some event. When the frame was over the image, the image was activated — if the user clicked on it, information about the mineral would appear. Of course I knew I could use CSS1 to create a frame around content, then use CSS-P to move the frame, but I wanted the interior of the frame to be transparent.

The solution I came up with was to create the frame using a one-pixel transparent GIF for the interior, setting its width and height to be the exact size of the frame I wanted. Using CSS-P, I could then move this GIF around from image to image. I also created two separate layers for each image: one that had the original image, which didn’t do anything when the reader clicked it, and another that had a framed, transparent GIF, which showed the mineral information layer when clicked. Figure 1 shows a snapshot of this page:

 


Figure 1

The one-pixel transparent GIF turned out to be much more than a simple placement and whitespace tool; it’s a handy tool that can be stretched and shrunk as needed and reused as often as necessary.

Positioning a menu for both old browsers and new
I soon found other uses for my newly rediscovered little GIF file, including a solution for a new Web page authoring problem I encountered.

I used to have a menu along the top of my pages that contained four separate images and text-based links just below the images. I used an HTML table to control the placement of images and text, ensuring that the images were placed directly next to each other and were aligned along the top of the page. One thing I never liked about this approach was that I preferred that menu text be layered over the images rather than displayed below them.

With CSS-P, I could position the images at the top of the page and use absolute positioning to place the menu text over the images. The problem I encountered, though, is that the page didn’t look very good when viewed with a pre-Navigator or IE 4.0 browser.

Instead, I used an HTML table along the top of the page, including the four images and their associated text in the table cells. However, I included these images and text in blocks delimited by <DIV> tags (these allow formatting to span multiple elements) and then used CSS-P to position the images and text so they overlapped. With this approach, older browsers see the page as they always have, as shown in Figure 2, but in the newer browsers the page has the new overlapped look, as shown in Figure 3.

 

Image Missing
Figure 2

 


Figure 3

There was one last problem with this approach, though. The thing with absolute positioning is that if you have it on content within a table element, the contents do not influence the table row’s height or the table cell’s width. This means that any other content on the page gets placed after the table, but overlaps the images and text because the table is not sized correctly.

I found that a simple solution for this was to use my trusty one-pixel transparent GIF as the first table cell and set it to the height I wanted the table to occupy. This sized the entire row to the height I needed to cover the positioned content — once again, a successful blend of the old and new.

Categories
Web Writing

Books at Amazon

Recovered from the Wayback Machine.

Dynamic HTML Power Guide authored by Shelley Powers, published in January, 1998. 1/19/98 – Finally, at long last, this book is in the bookstores!“Dynamic HTML” book provides over 100 examples covering both Microsoft Internet Explorer 4.0 and Netscape Navigator 4.0 Dynamic HTML. This includes an explanation and demonstration of the style specification standard CSS1, and provides an overview of both VBScript and JavaScript 1.2, to assist in understanding examples written with both scripting languages. The book also has separate sections providing comprehensive coverage and demonstrations of the IE 4.0 and Navigator 4.0 scripting object models.

The end of the book features a section containing complex cross-browser examples such as an online presentation, magazine, game, and catalog page.

What cross-browser techniques will you learn? How to layer content, use layers and DIV blocks together, hide and show content, two different techniques for drag and drop, event capturing, clipping, element movement, and yes, even how to replace content in a page AFTER the page has been loaded. This is in addition to how to maintain DHTML “state”, and how to create cross-browser scripting objects that take care of browser differences.

The book also has fun with each individual browser. Using forms and layers together. Hiding and showing form “hints”. Learn how to emulate the IE shadow and alpha visual filters in Navigator. Play with drag and drop art. Have some fun with Microsoft’s visual and transition filters. Hide and show content, or change the style attribute for content.

The book has been tested against the delivered IE 4.0 product, and Navigator 4.4, on Windows95 and NT.

Book is for an intermediate/advanced audience.

Dynamic Web Publishing Unleashed co-authored by Shelley Powers, published in December, 1997 by SAMS.Book is an overview of Web-based technologies including HTML 4.0, DHTML, CSS1, Scripting, Java 1.1, Channels, server-side techniques and more. If you are new to Web, or have only worked with one or two Web technologies this book can help you “catch up” with the seemingly endless components of Web development. The book follows more of a reference format, meaning that each section can be read in any order. The book also follows the philosophy of “less talk, more code”.

The Channels and VRML chapters, and my commentary chapter on the future of the Web technologies, are online at SAMS at http://www.mcp.com/sites/1-57521/1-57521-363-x/.

Note that there is some confusion at various online bookstores about the size of the book. It is a little over 800 pages in length, not including the online chapters. Also note that this book is not by the same author as Web Publishing Unleashed, follows a different format, and contains new content.

Perl from the Ground Up, by Osborne McGraw-Hill, due to be published in 1997.I wrote the chapters on Object-Oriented Perl, and Perl and the Internet-based libraries. The book promises to be a good overall discussion of Perl that does not require any previous Perl experience.
Java Unleashed 1.1 – published by SAMS, 1997.I wrote the chapters on the SQL classes, and Java Databases. This book provides a good, overall, coverage of the JDK 1.1, including coverage of RMI, JDBC, threads, JAR, networking, sockets, applets, and much more.
Maximum Java 1.1 – published by SAMS, 1997.I wrote the chapters on Managing Media, Finding and Using Resources, and the Java Commerce API. This is a book that covers advanced Java topics such as the Java and VRML 2.0, Reflection and Introspection, factory objects, serialization and persistence and other. This book takes off from where others end.
PowerBuilder 5 How To, co-authored by Shelley Powers, published in 1996 by Waite Group Press.Book is fairly large and answers some of the most common PB 5.0 questions, using the Waite Group Press “Question and Answer” format popular with the “How To” series. In addition, this was the first book on the shelves that provided examples for using the DataWindow plug-ins.

I am particularly proud of the section I wrote on creating the different types of applications, demonstrating that PB applications do not need to be MDI (multiple document interface) apps, only.

Using Perl 5 for Web Programming, co-authored by Shelley Powers, published by Que, 1996.This is an Amazon Bookstore bestseller. I particularly like the company newsletter example I created for this book.