Special Edition Using HTML 4

Previous chapterNext chapterContents


- 18 -
Positioning HTML Elements

by Jerry Honeycutt

Understanding CSS Positioning

In the desktop publishing world, layers are rectangular blocks of text and artwork that you can position anywhere on the page. You can also overlap layers so that one is hidden behind another or so that one bleeds through another. Publishers use layers to create some pretty awesome layouts. Take a look at any print advertisements or brochures, for example. Chances are, the publisher used layers.

While desktop publishers might take layering for granted (even the simplest of desktop publishing programs allow you to create and overlap layers), HTML designers don't. Because HTML is streaming, they've never had the capability to overlap blocks of text and artwork. That is, each preceding HTML element is displayed before the next--in order. HTML has never provided for the positioning of an HTML element, much less for overlapping HTML elements.

Until now--HTML 4.0 introduces the CSS positioning. If you're unsure of how to use style sheets, you should review Chapter 17, "Applying Cascading Style Sheets."

Positioning an HTML Element

You define an element's position using a style. Within a style's rule, you assign either RELATIVE or ABSOLUTE to the POSITION property. If you assign RELATIVE, the browser positions the element relative to its normal position (the location at which it would naturally appear). If you assign ABSOLUTE to POSITION, the browser positions the element relative to the parent container, whether it be the document or some other element, such as a <DIV> tag. In most cases, you use ABSOLUTE to place an element at an exact location relative to its parent. Use RELATIVE if you want to nudge an element slightly out of its normal location.

You position an element using a style's TOP and LEFT properties, like this:

#element {position: absolute; top: 100; left: 20}

When you assign the example style to an element, the browser positions it 100 pixels down and 20 pixels to the right of document's top, left-hand corner.

LEFT and TOP are represented in pixels, by default, and are relative to the top, left corner of the containing area within the HTML document. For example, to position an element 10 pixels from the left edge of the browser window and 40 pixels from the top edge, use LEFT=10 and TOP=40. The browser draws the HTML document as though the positioned element does not exist, and then the element is overlapped with the Web page at the given offset. You can also assign percentages to LEFT and TOP, which represent a percentage of the parent container's width and height, respectively. Listing 18.1 positions an element in the middle of the Web page. As shown in Figure 18.1, the contents of the HTML document bleed through the contents of the positioned element because it's transparent.

Listing 18.1  Positioning an Element in the Middle of the Page

<HTML>
<HEAD>
<TITLE>Listing CC.1</TITLE>
</HEAD>
<STYLE TYPE="text/css">
  #example {position: absolute; top: 40; left: 100}
</STYLE>
<BODY>
<IMG ID=example SRC=init.gif>
<P>You can position an element anywhere you like.</P>
<P>This element is positioned, however, so that it overlaps
the HTML document below it. Notice how this text displays
through the image's transparent background.</P>
<P>This element is positioned, however, so that it overlaps
the HTML document below it. Notice how this text displays
through the image's transparent background.</P>
<P>This element is positioned, however, so that it overlaps
the HTML document below it. Notice how this text displays
through the image's transparent background.</P>
<P>This element is positioned, however, so that it overlaps
the HTML document below it. Notice how this text displays
through the image's transparent background.</P>
</BODY>
</HTML>

FIG. 18.1
You can position the element wherever you want on the browser window.

Changing the Size of an Element

You can change the height and width of the rectangular area occupied by an element. You use the WIDTH and HEIGHT properties. Like TOP and LEFT, you can assign a length or percentage to either of these properties. You can also assign AUTO to them and the browser automatically determines the appropriate width and height.

#element {position: absolute; top: 20; left: 20; width: 100; height: 100}

You don't use the WIDTH attribute to define the element's absolute width. This property suggests a width for purposes of wrapping the text contained within the element. If the text doesn't completely fill the element, however, the element is not actually as wide as the specified value. If you're inserting an image (or another element the browser can't wrap) inside an element, and the image is wider than the suggested width, the element's actual width is bigger than the suggested value.


TIP: The OVERFLOW property determines what the browser does in the case that an element's contents are larger than the element's size. Assign NONE, and the contents are not clipped. Assign CLIP, and the browser chops off the content to fit in the rectangular area. Assign SCROLL, and the browser allows you to scroll the window so you can see more of it.

Listing 18.2 shows an example of an element that is 160 pixels wide and positioned 80 pixels from the top. As shown in Figure 18.2, the text wraps within the element, just like it would wrap within a table cell that's 160 pixels wide.

Listing 18.2  Specifying the Width of an Element

<HTML>
<HEAD>
<TITLE>Example 2</TITLE>
</HEAD>
<STYLE TYPE="text/css">
  #example {position: absolute; top: 80; left: 40; width: 160}
</STYLE>
<BODY>
<DIV ID=example>
  This text is within the DIV tag. Notice how its
  length is controlled by the width property.
</DIV>
</BODY>
</HTML>


TIP: You can use positioned elements to perform many of the same formatting tricks you've learned to do with the <TABLE> tag.

FIG. 18.2
You can leave either the TOP or LEFT attributes out, and the browser positions the element as though the omitted attribute is 0.

Overlapping Multiple Elements

You can cause elements to overlap by setting each element's TOP and LEFT attributes so that one appears on top of another. Figure 18.3 shows two elements. The first contains a handful of text and has a background image. The second element contains an image with a transparent background. The second element is positioned so that it overlaps the first (see Listing 18.3).

Listing 18.3  Overlapping Elements

<HTML>
<HEAD>
<TITLE>Example 3</TITLE>
</HEAD>
<STYLE TYPE="text/css">
  #example {position: absolute; top: 40; left: 60}
  #another {position: absolute; top: 80; left: 200}
</STYLE>
<BODY>
<DIV ID=example>
  <B>This is the first layer. It's behind the second layer.</B><BR>
  <B>This is the first layer. It's behind the second layer.</B><BR>
  <B>This is the first layer. It's behind the second layer.</B><BR>
  <B>This is the first layer. It's behind the second layer.</B><BR>
  <B>This is the first layer. It's behind the second layer.</B><BR>
  <B>This is the first layer. It's behind the second layer.</B><BR>
  <B>This is the first layer. It's behind the second layer.</B><BR>
  <B>This is the first layer. It's behind the second layer.</B><BR>
</DIV>
<IMG ID=another SRC=init.gif>
</BODY>
</HTML>

FIG. 18.3
Because the image in the second element has transparent areas, the content behind this element bleeds through.


NOTE: By default, the browser draws overlapped elements in the order it encounters them. That is, it draws the first element, overlaps that with the next element, and so on.

If you don't like the order in which the browser overlaps elements, you can change it. The most straightforward way is by using the Z-INDEX property, which defines the stacking order for elements:

#example {position: absolute; top: 100; left: 100; z-index: 1}

You set this attribute to any positive integer value. An element with a stacking order larger than another draws over the other element. For example, an element with a stacking order of 10 overlaps an element with a stacking order of five. On the other hand, an element with a stacking order of three is overlapped by an element with a stacking order of five.

Listing 18.4 is an example of three elements, each of which uses the Z-INDEX attribute to define its stacking order. The first has a stacking order of two; the second has a stacking order of one, and the third has a stacking order of three. Thus, the browser draws the second element first, the first element second, and the third element last, as shown in Figure 18.4.

Listing 18.4  Using Z-INDEX

<HTML>
<HEAD>
<TITLE>Example 4</TITLE>
</HEAD>
<STYLE TYPE="text/css">
  #ex1 {position: absolute; top: 40; left: 60; z-index: 2}
  #ex2 {position: absolute; top: 80; left: 200; z-index: 1}
  #ex3 {position: absolute; top:100; left: 80; z-index: 3}
</STYLE>
<BODY>
<DIV ID=ex1>
<B>This is the first element. It's in the middle.</B><BR>
<B>This is the first element. It's in the middle.</B><BR>
<B>This is the first element. It's in the middle.</B><BR>
<B>This is the first element. It's in the middle.</B><BR>
<B>This is the first element. It's in the middle.</B><BR>
<B>This is the first element. It's in the middle.</B><BR>
<B>This is the first element. It's in the middle.</B><BR>
<B>This is the first element. It's in the middle.</B><BR>
</DIV>
<DIV ID=ex2>
<B>This is the second layer. It's behind the first layer.</B><BR>
<B>This is the second layer. It's behind the first layer.</B><BR>
<B>This is the second layer. It's behind the first layer.</B><BR>
<B>This is the second layer. It's behind the first layer.</B><BR>
<B>This is the second layer. It's behind the first layer.</B><BR>
<B>This is the second layer. It's behind the first layer.</B><BR>
<B>This is the second layer. It's behind the first layer.</B><BR>
<B>This is the second layer. It's behind the first layer.</B><BR>
</DIV>
<IMG ID=ex3 SRC=init.gif>
</LAYER>
</BODY>
</HTML>

FIG. 18.4
The Z-INDEX property essentially defines the order in which each element is drawn.


TIP: You can overlap several elements at the same position, define each element's stacking order in sequence, and then peel away the elements one at a time (using a script) to create a simple animation.

Nesting Positioned Elements

So far, you've only seen cases in which a handful of elements were added to the HTML document. They were siblings in that one was not contained within another. You can insert one element inside another, however, to create a parent-child relationship. In that case, the child (inside) is relative to the parent (outside). Thus, if you position an element called PARENT and locate it at 10, 10; and nest an element inside of PARENT called CHILD located at 5, 5; the child element actually displays at 15, 15 on the HTML document. If you move the parent element to 20, 20, the child element moves right along with it to 25, 25.

Listing 18.5 shows you an example of nested elements. The parent element contains an image of a rough Christmas tree. It contains a number of nested elements that represent bulbs. The coordinates of each nested element are relative to the upper-left corner of the parent. If you moved the Christmas tree to another location on the Web page, the bulbs would move right along with it (see Figure 18.5).

Listing 18.5 esting Elements

<HTML>
<HEAD>
<TITLE>Example 5</TITLE>
</HEAD>
<BODY>
<DIV STYLE="position: absolute; top: 100; left: 100">
<IMG SRC=xtree.gif>
  <IMG STYLE="position: absolute; top: 140; left: 60" SRC=ball1.gif>
  <IMG STYLE="position: absolute; top: 20; left: 100" SRC=ball2.gif>
  <IMG STYLE="position: absolute; top: 130; left: 120" SRC=ball1.gif>
  <IMG STYLE="position: absolute; top: 170; left: 140" SRC=ball2.gif>
  <IMG STYLE="position: absolute; top: 200; left: 120" SRC=ball2.gif>
  <IMG STYLE="position: absolute; top: 80; left: 80" SRC=ball3.gif>
  <IMG STYLE="position: absolute; top: 90; left: 125" SRC=ball3.gif>
  <IMG STYLE="position: absolute; top: 200; left: 60" SRC=ball3.gif>
  <IMG STYLE="position: absolute; top: 200; left: 180" SRC=ball3.gif>
</DIV>
</BODY>
</HTML>

FIG. 18.5
By capturing the mouse events for each bulb, you can allow the user to move the bulbs around on the Christmas tree.

Positioning Elements with Scripts

You get a lot of publishing capabilities just from being able to position an element anywhere on an HTML document and overlap it with others. You can create a variety of special effects, however, by attaching a script to an element and using that script to hide or show it--you can even move it around the browser window.

Given an element's ID, you reference it using the object model (see Chapter 19, "Scripting the Object Model"), like this:

document.all.item(id, 0)

id is the element's ID. The 0 indicates that you want the first occurrence of any element with that particular ID.

To access one of the styles, use the style object by appending .style to the object representing the element; then append the name of the style you're accessing to the end of that. Here's an example:

document.all.item(id, 0).style.property

Using a Script to Hide or Show an Element

You can use a script to hide and show elements on the HTML document. For example, you can create an element that you only want to display when the user moves the mouse across an image. In that case, you'd set the element's VISIBILITY property to "hidden" so that it's not initially displayed. Then, in the image's OnMouseOver event, set the element's visibility property to "", like this:

document.all.item(id, 0).style.property = "";

Listing 18.6 shows you an example that does something similar. It uses JavaScript, but you can use another scripting language just as well. It contains three elements and three buttons. The script associated with each button toggles the visibility of each element. Click a button associated with a visible element and the script makes the element invisible (see Figure 18.6).

Take a look at the function called ToggleFirst(). It toggles the state of the flag called ShowFirst, which indicates whether the element called FIRST is visible. It then sets the element's visibility property to "hidden" if ShowFirst is false; otherwise, it sets the property to "", which causes the element to become visible.

Listing 18.6  Hiding and Showing Elements

<HTML>
<HEAD>
<TITLE>Example 6</TITLE>
</HEAD>
<STYLE TYPE="text/css">
  #first {position: absolute; top: 80; left: 60}
  #second {position: absolute; top: 120; left: 200}
  #third {position: absolute; top: 140; left: 180}
</STYLE>
<SCRIPT LANGUAGE=JAVASCRIPT>
  ShowFirst = true;
  ShowSecond=false;
  ShowThird=true;
  function ToggleFirst()
  {
    ShowFirst = !ShowFirst;
    document.all.item("first", 0).style.visibility = ShowFirst ? "" : 
        "hidden";
  }
  function ToggleSecond()
  {
    ShowSecond = !ShowSecond;
    document.all.item("second", 0).style.visibility = ShowSecond ? "" : "hidden";
  }
  function ToggleThird()
  {
    ShowThird = !ShowThird;
    document.all.item("third", 0).style.visibility = ShowThird ? "" : 
         "hidden";
  }
</SCRIPT>
<BODY>
<DIV ID=first>
<B>This is the first layer. It's in the middle.</B><BR>
<B>This is the first layer. It's in the middle.</B><BR>
<B>This is the first layer. It's in the middle.</B><BR>
<B>This is the first layer. It's in the middle.</B><BR>
<B>This is the first layer. It's in the middle.</B><BR>
<B>This is the first layer. It's in the middle.</B><BR>
<B>This is the first layer. It's in the middle.</B><BR>
<B>This is the first layer. It's in the middle.</B><BR>
</DIV>
<DIV ID=second STYLE="visibility: hidden">
<B>This is the second layer. It's behind the first layer.</B><BR>
<B>This is the second layer. It's behind the first layer.</B><BR>
<B>This is the second layer. It's behind the first layer.</B><BR>
<B>This is the second layer. It's behind the first layer.</B><BR>
<B>This is the second layer. It's behind the first layer.</B><BR>
<B>This is the second layer. It's behind the first layer.</B><BR>
<B>This is the second layer. It's behind the first layer.</B><BR>
<B>This is the second layer. It's behind the first layer.</B><BR>
</DIV>
<IMG ID=third SRC=init.gif>
<FORM NAME=TOGGLE>
  <TABLE ALIGN=CENTER>
    <TD>
      <INPUT NAME=FIRST TYPE=BUTTON VALUE="Toggle First Layer "        onclick="ToggleFirst();">
    </TD>
    <TD>
      <INPUT NAME=SECOND TYPE=BUTTON VALUE="Toggle Second Layer"        onclick="ToggleSecond();">
    </TD>
    <TD>
      <INPUT NAME=THIRD TYPE=BUTTON VALUE="Toggle Third Layer "        onclick="ToggleThird();">
    </TD>
  </TABLE>
</FORM>
</BODY>
</HTML>

FIG. 18.6
As you click buttons to hide an element, the browser peels that layer away, unveiling what's underneath.


TIP: In Windows, you've seen dialog boxes that contain a button with the text More>>. When you click that button, additional fields are presented. You can achieve the same effect in an HTML form by attaching a script to a form's button that shows another form hidden within a <DIV> tag.

Moving an Element with a Script

Besides showing and hiding an element, you can also move it around on the Web page. You can use this to create some pretty fancy animation, such as a curtain that appears to open, unveiling the contents of the page. Moving an element around is easy. You set the value of the left and top properties (using posLeft and posTop so that you don't have to change the length as a string with units), as shown in Listing 18.7 and Figure 18.7.

This example contains two elements. It also contains four buttons, label Up, Down, Left, and Right. Each button is associated with a function that moves the second element in the appropriate direction. For example, the Up function subtracts 10 from the second element's top property, which has the effect of moving the element up 10 pixels. The Right function adds 10 to the second element's left property, which has the effect of moving the element right 10 pixels.

Listing 18.7  Moving an Element with a Script

<HTML>
<HEAD>
<TITLE>Example 7</TITLE>
<SCRIPT LANGUAGE=JAVASCRIPT>
  function Up()
  {
    document.all.item("second", 0).style.posTop -= 10;
  }
  function Down()
  {
    document.all.item("second", 0).style.posTop += 10;
  }
  function Left()
  {
    document.all.item("second", 0).style.posLeft -= 10;
  }
  function Right()
  {
    document.all.item("second", 0).style.posLeft += 10;
  }
</SCRIPT>
</HEAD>
<BODY>
<DIV STYLE="position: absolute; top: 200; left: 300"; z-order: 2">
<B>This is the first layer. It's always on top.</B><BR>
<B>This is the first layer. It's always on top.</B><BR>
<B>This is the first layer. It's always on top.</B><BR>
<B>This is the first layer. It's always on top.</B><BR>
<B>This is the first layer. It's always on top.</B><BR>
<B>This is the first layer. It's always on top.</B><BR>
<B>This is the first layer. It's always on top.</B><BR>
<B>This is the first layer. It's always on top.</B><BR>
<B>This is the first layer. It's always on top.</B><BR>
</DIV>
<IMG ID=second STYLE="position: absolute; top: 180; left: 0; z-order: 1" SRC=init.gif>
<FORM NAME=BUTTONS>
<TABLE>
<TR>
<TD></TD>
<TD ALIGN=CENTER>
<INPUT WIDTH=100% NAME=UP TYPE=BUTTON VALUE="Up" onclick="Up();">
</TD>
<TD></TD>
</TR>
<TR>
<TD ALIGN=CENTER>
<INPUT NAME=LEFT TYPE=BUTTON VALUE="Left " onclick="Left();">
</TD>
<TD></TD>
<TD ALIGN=CENTER>
<INPUT WIDTH=100 NAME=RIGHT TYPE=BUTTON VALUE="Right" onclick="Right();">
</TD>
</TR>
<TR>
<TD></TD>
<TD ALIGN=CENTER>
<INPUT WIDTH=100 NAME=DOWN TYPE=BUTTON VALUE="Down " onclick="Down();">
</TD>
<TD></TD>
</TR>
</TABLE>
</FORM>
</BODY>
</HTML>

Expanding Forms: An Example

There are two types of users in this world: basic and advanced. With forms, you find many cases in which a basic user needs to fill in only a few of the simpler fields, while the advanced user needs to fill in all of the fields, including the more advanced fields.

You can display all of the form's fields at one time and let the basic user ignore the advanced fields or you can hide the advanced fields and let the advanced user get to them by clicking a special button. The latter is the approach that Windows 95 and Windows NT 4.0 take in many cases. Have you ever seen a dialog box in Windows with a button labeled Advanced or More? When the user clicks one of these buttons, the dialog box unfolds to show more fields.

With CSS positioning, hiding a portion of a form until a user clicks a button is easy. Listing 18.8 is just such an example. At the bottom of this HTML document, you see a portion of the form sandwiched in a <DIV> tag. The <DIV> tag's visibility property is initially set to "hidden". The function OpenMore toggles the visibility of the hidden portion of the form and changes the text displayed in the button to reflect the state of the form.

FIG. 18.7
As you move the second element by the first, it disappears under the first element, because the second element has a larger z-order.

Listing 18.8  Expanding a Form

<HTML>
<HEAD>
<TITLE>Example 8</TITLE>
<SCRIPT LANGUAGE=JAVASCRIPT>
blnMoreIsUp = false;
// Display the hidden form if it's not already displayed. Otherwise, hide it.
// Also, change the text in the button to reflect the current state of the hidden form.
function OpenMore()
{
  blnMoreIsUp = !blnMoreIsUp;
  document.all.item("MORE", 0).style.visibility = blnMoreIsUp ? "" : "hidden";
  document.FEEDBACK.FEEDBACK_MORE.value = blnMoreIsUp ? "Less<<" : "More>>";
}
</SCRIPT>
</HEAD>
<BODY>
<FORM NAME=FEEDBACK METHOD=GET ACTION="mailto:jerry@honeycutt.com" OnSubmit="return IsValid()">
  <TABLE CELLPADDING=10>
   <TR>
      <TD VALIGN=TOP>
         <B>Please provide your e-mail address:</B><BR>
         <INPUT NAME=FEEDBACK_MAIL TYPE=TEXT SIZE=40>
      </TD>
      <TD VALIGN=TOP>
        <B>How did you find our site:</B><BR>
        <SELECT NAME=FEEDBACK_HOW SIZE=1>
           <OPTION VALUE=1>AltaVista
           <OPTION VALUE=2>Excite
           <OPTION VALUE=3>Lycos
           <OPTION VALUE=4>Yahoo!
           <OPTION VALUE=5>WebCrawler
           <OPTION VALUE=6>Friend
           <OPTION VALUE=7>Other Link
      </SELECT>
      </TD>
    <TR>
      <TD VALIGN=TOP ROWSPAN=2>
        <B>Tell us what you think about our Web site:</B><BR>
        <TEXTAREA NAME=FEEDBACK_MEMO COLS=45 ROWS=8>
        </TEXTAREA>
      </TD>
      <TD VALIGN=TOP>
        <B>How did we rate?</B><BR>
        <TABLE BORDER=1>
          <TR ALIGN=CENTER>
            <TH></TH><TH>Yes</TH><TH>No</TH>
          </TR>
          <TR ALIGN=CENTER>
            <TD ALIGN=LEFT>
              Did this site load fast enough?
            </TD>
            <TD>
              <INPUT NAME=FEEDBACK_SPEED TYPE=RADIO>
            </TD>
            <TD>
              <INPUT NAME=FEEDBACK_SPEED TYPE=RADIO>
            </TD>
          </TR>
          <TR ALIGN=CENTER>
            <TD ALIGN=LEFT>
              Did you find the graphics interesting?
            </TD>
            <TD>
              <INPUT NAME=FEEDBACK_GRAPHIC TYPE=RADIO>
            </TD>
            <TD>
              <INPUT NAME=FEEDBACK_GRAPHIC TYPE=RADIO>
            </TD>
          </TR>
          <TR ALIGN=CENTER>
            <TD ALIGN=LEFT>
                Was the content suitable?
            </TD>
            <TD>
              <INPUT NAME=FEEDBACK_CONTENT TYPE=RADIO>
            </TD>
            <TD>
              <INPUT NAME=FEEDBACK_CONTENT TYPE=RADIO>
            </TD>
          </TR>
         </TABLE>
      </TD>
    </TR>
    <TR ALIGN=RIGHT>
      <TD>
         <TABLE WIDTH=100%>
           <TD ALIGN=LEFT>
             <INPUT NAME=FEEDBACK_MORE TYPE=BUTTON VALUE="More>>"               OnClick="OpenMore()">
           </TD>
           <TD>
             <INPUT NAME=FEEDBACK_RESET TYPE=RESET VALUE=Clear>
             <INPUT NAME=FEEDBACK_SUBMIT TYPE=SUBMIT VALUE=Submit>
           </TD>
         </TABLE>
      </TD>
     </TR>
  </TABLE>
  <!-- This DIV contains the hidden part of the form that the user sees when          they click on More>>. The event-handler at the top of this file shows          the layer. -->
  <DIV ID=MORE STYLE="visibility: hidden">
    <TABLE CELLPADDING=10>
      <TR>
        <TD>
          <B>Type the URL of your home page:</B><BR>
          <INPUT NAME=FEEDBACK_URL TYPE=TEXT SIZE=60>
        </TD>
        <TD>
          <B>Type your phone number:</B><BR>
          <INPUT NAME=FEEDBACK_PHONE TYPE=TEXT SIZE=32>
        </TD>
      </TR>
    </TABLE>
  </DIV>
</FORM>
</BODY>
</HTML>

Figure 18.8 shows the resulting form with the hidden form expanded.

FIG. 18.8
If the user clicks Less<< to hide the advanced fields, the browser still keeps any data that the user typed in these fields.


Previous chapterNext chapterContents


Macmillan Computer Publishing USA

© Copyright, Macmillan Computer Publishing. All rights reserved.