A List Apart

Menu
Issue № 68

DOM Design Tricks

by Published in CSS, HTML, JavaScript

The following tutorials will show you how to use the W3C Document Object Model (DOM), Style Sheets, and JavaScript to add value to your website’s content.

Note: All the examples are written to work in Mozilla, which is fully compliant with Level 1 Cascading Style Sheets as defined by the World Wide Web Consortium. I have decided to not show much non-standard code for other browsers in the examples. I believe that the sooner authors start writing to the standards, the sooner readers will switch browsers in order to enjoy the new capabilities.

It should be noted that all the examples here also work in IE5 for Windows and Macintosh. While IE5 does not claim to fully support the W3C DOM—and does not fully support it—the browser is moving in the right direction. However, to make the examples work in IE, it was necessary to add some additional, workaround code. (Sigh.)

Hiding and Showing Information

If you’ve been using style sheets, you may already know about thevisibilityproperty. You can use it to reveal information when it’s needed, as in the example below: (See how it was written)

This is to be an example.

This works nicely, but has one drawback—the hidden text still takes up room on the page. That᾿s why, before you revealed the picture, this text appears to have an unnatural amount of blank space above it. It᾿s also why the two different areas don’t show up in the same location.

We could useposition:absolute;to make the hidden areas appear at the same location, but if a user set her default font size to a large value, our carefully positioned areas might overwrite other text.

Visibility Example Code

The two hidden areas are written like this in the HTML:


<div id="picDiv">
  <img src="brush.jpg" width="119" height="131">
</div>
<div id="specDiv">
  <table border="0">
    <tr>
      <td align="right">Size:</td>
      <td> 12 cm x 13.5 cm </td>
    </tr>
    ...
  </table>
</div>

The stylesheet for the page has these entries to ensure that neither area is visible when the page loads:


#picDiv {
  visibility: hidden;
}

#specDiv {
  visibility: hidden;
}

And the code attached to the buttons looks like this:


<script language="JavaScript" src="domUtils.js">
</script>
<script language="JavaScript">
function showPic() {
  setIdProperty( 'specDiv', 'visibility', 'hidden' );
  setIdProperty( 'picDiv', 'visibility', 'visible' );
}

function showSpec() {
    setIdProperty( 'picDiv', 'visibility', 'hidden' );
    setIdProperty( 'specDiv', 'visibility', 'visible' );
}
</script>

Note: In order to avoid display errors for this article in Navigator 4 (which is obviously not DOM-compliant), the code was kludged as follows:


#picDiv {
  position: relative;
  visibility: hidden;
}

#specDiv {
  position: relative;
  visibility: hidden;
}

Note: the setIdProperty() function comes from the DOM Utilities include file, which was developed in a previous article.

The Display Property

What we really want is a way to specify that a<div>should not take up any space on the page when it’s not being displayed, and thedisplayproperty will let us do exactly that. We write the HTML for the two separate areas:


<div id="picDiv">
  <img src="brush.jpg" width="119" height="131">
</div>
<div id="specDiv">
  <table border="0">
    <tr>
      <td align="right">Size:</td>
      <td> 12 cm x 13.5 cm </td>
    </tr>
    ...
  </table>
</div>

Then set up our stylesheet as follows:


#picDiv {
  display: none;
}

#specDiv {
  display: none;
}

Thenonevalue for thedisplayproperty tells the browser to completely ignore that division; the page is treated as if the HTML weren’t there at all. Thus, neither #picDiv nor #specDiv will take up any space when the browser renders the page.

Now we have to create functions to change thedisplayattributes; these functions will be invoked by the buttons’ onClick attribute.


function showPic() {
  setIdProperty( 'specDiv', 'display', 'none' );
  setIdProperty( 'picDiv', 'display', 'block' );
}

function showSpec() {
  setIdProperty( 'picDiv', 'display', 'none' );
  setIdProperty( 'specDiv', 'display', 'block' );
}

You already know what none does; we’ll explain the block value a little later. The setIdProperty() function comes from the DOM Utilities include file, which was developed in a previous article. Now let’s see what it looks like:

Example ofdisplay.

Display Values

There are many possible values for display, but the three most important are none, block, and inline. As we mentioned before, setting display to none takes an element out of the page flow entirely; the browser ignores it. The last two of these refer to the context in which HTML displays elements. block elements begin on a new line. Examples are <h1>, <p>, <ol>, and <div>. inline elements are laid out one after the other and flow in line with their surrounding elements. Examples are <b>, <i>and <span>

By changing display appropriately, we can cause a <div> to appear in any of these formatting contexts. Here’s an example:

Example of displaywithin a paragraph.

Expanding Text

Let’s put the display property to work. Click the plus sign icons in the paragraph below.

Example of expanding <span>s in a <blockquote>.

The contracted and expanded <span>s come in numbered pairs with ids starting with c for the contracted span and efor the expanded span. Here’s some of the HTML from this page:


<span id="c1" class="short"><a href="javascript:swapDiv(1, true)"><img
    alt="more" src="plus.gif" border="0" width="12" height="12"></a>
</span>
<span id="e1" class="long">
<a href="javascript:swapDiv(1,false)"><img src="minus.gif"
    alt="less" border="0" width="12" height="12"></a>
which would otherwise require use of a frame or a
pop-up window
</span>.

With this stylesheet:


.short {
  display: inline;
}

.long {
  display: none;
  background-color: #99ff99;
}

And this JavaScript to tie it all together :


function swapDiv(divNum, expanding) {
  if (expanding) {
    setIdProperty( 'c' + divNum, 'display', 'none' );
    setIdProperty( 'e' + divNum, 'display', 'inline' );
  } else {
    setIdProperty( 'e' + divNum, 'display', 'none' );
    setIdProperty( 'c' + divNum, 'display', 'inline' );
  }
}

Expanding Menus

Example of expanding menus.

And finally, it’s possible to do hierarchical menus quite easily, as shown in the code below. Again, click the plus and minus signs to expand and contract the menu at the left.

These are just two ideas of how to use the display property to enhance your website’s content. If you have other ideas, please let me know.

As to the code, here are the stylesheet and script, and a portion of the HTML.


<style type="text/css">

<!--
.submenu {
    display: none;
    margin-left: 2em;
}
.mhead {
    background-color: #ccccff;
    display: block;
    font-size: 150%;
}
-->
</style>

<script language="JavaScript">
function showMenu(divNum) {
  if (getIdProperty( 's' + divNum, 'display') != 'block' ) {
    setIdProperty( 's' + divNum, 'display', 'block' );
    document.images['i' + divNum].src = 'minus.gif';
  } else {
    setIdProperty( 's' + divNum, 'display', 'none');
    document.images['i' + divNum].src = 'plus.gif';
  }
}
</script>

<div class="mhead">
<a href="javascript:showMenu(0);"><img src="plus.gif"
    name="i0" border="0" width="12" height="12"></a> Search Engines</a>

</div>
<div class="submenu" id="s0">
<a href="http://www.google.com/">Google</a> <br>
<a href="http://www.yahoo.com/">Yahoo!</a> <br>
<a href="http://www.excite.com/">Excite</a> <br>
<a href="http://www.lycos.com/">Lycos</a>
</div>

No Comments

  1. Sorry, commenting is closed on this article.