Absolute positioning practical examples

By John Faulds

If you've read Absolute Positioning Pitfalls, you're probably wondering when you can use absolute positioning.

Well, I generally find that I use it not for laying large areas of a layout, areas that contain multiple other elements, but rather for positioning individual elements in relation to other elements. (It certainly can be used for creating large layout areas in certain instances, but I'm not going to cover that here.)

The thing that most newcomers to CSS fail to appreciate is how a positioning context for a certain element can be reset. What does this mean? Well, ordinarily, if no element in a layout has position: relative or position: absolute set on it, the only element that does have a positioning context is the document window. This means that when you set your top, right, bottom or left coordinates, they're taking their 0 point from the top left of the window.

This can be reset, however, by setting either position: relative or position: absolute on an element. When this is done, any descendant element then takes its coordinates from the top left of the parent container, rather than the document window.

So, enough of the theory, let's see some examples. The four examples I'm going to give here are the ones that I use absolute positioning for most often:

  1. The Gilder/Levin image replacement techique
  2. Creating a horizontal navigation bar
  3. Suckerfish dropdowns

1 The Gilder/Levin image replacement techique

This method (or variants of it) has been my preferred image replacement (IR) technique (replacing text on the page with a background image) due to its greater accessibility. Most IR techniques involve removing the text from the screen with a large negative text indent or by setting it to display: none or visibility: hidden.

This is fine for most users, but for those who surf with images turned off, they don't get to see any text. The Gilder/Levin method, although requiring an extra, empty pair, does mean that users with images turned off will still be able to read the text.

Let's take a look at how it works:

<h4 class="ir" id="#heading1">Headline<span></span></h4>
.ir {
  position: relative;
  margin: 0;
  padding: 0;
  /* hide this from IE5 Mac */
  /* \*/
  overflow: hidden;
  /* */
}
.ir span {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1; /*for Opera 5 and 6*/
}
#heading1, #heading1 span {
  height: 100px;
  width: 300px;
  background: url(heading1.gif)
  top left no-repeat;
}

What we’re actually doing is not ‘replacing’ the text, but covering it up so that it’s still there for when images are turned off. The covering up is accomplished by setting position: relative on the element containing the text to establish a new positioning context. So any element contained within our heading (in this case, the <h4>) will be placed relative to the top left of the <h4>.

And that’s what the empty span is doing. As spans are inline elements, we set it to display: block so that it can be dimensioned, give it the width & height of our image and place the image as background of the span. We then place it absolutely at the top left (top: 0; left: 0;) of the <h4>, thus covering up the text.

The only thing left to do is to set overflow: hidden; on the containing element* so that the text doesn’t peek out underneath if the user resizes their text. And it looks something like this:

Your heading

Why have we used both a class and an ID for the heading? So we can reuse the basic styles for the image replacement elsewhere. The only thing unique to each element will be the image itself and its dimensions and we attach those to individual IDs.

The other thing to remember about this method is that your image must not have any transparent areas or your text will show through from behind.

* It should be pointed out that IE5 Mac has some issues with this method of image replacement in certain circumstances. We’ll take a closer look at that in Single image replacement rollovers with Suckerfish dropdowns.

There are various ways of turning an unordered list (<ul>) into a horizontal navigation bar. You can set the list items (<li>) to float: left or display: inline or you can use absolute positioning. The last option is probably most useful when creating an image-replaced horizontal navigation bar but for the purposes of demonstrating the technique, we’ll just use a plain text list.

<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>

The above code gives us this:

  • Item 1
  • Item 2
  • Item 3

Now let’s put it on one line. We’ll add some IDs to each <li> so we can position each one individually.

<ul>
  <li id="list-item1">Item 1</li>
  <li id="list-item2">Item 2</li>
  <li id="list-item3">Item 3</li>
</ul>
ul {
  position: relative;
  list-style:none;
}
li {
  position: absolute;
  top: 0;
}
#list-item1 {
  left: 0;
}
#list-item2 {
  left: 10em;
}
#list-item3 {
  left: 35em;
}
  • Item 1
  • Item 2
  • Item 3

By setting a new positioning context on the <ul> with position: relative,we can then place all the list items at the same vertical point. We can then position wherever we want them on the horizontal axis with different left values. We could also place them in different orders this way. (You’ll need to remember to apply proper clearing for this technique.)

3 Suckerfish dropdowns

I’m not going to go into the exact workings of probably the most popular CSS-based dropdown menu system as it has been done already at HTMLDog, but I will point out the part that relates to the discussion in hand.

#nav li ul {
  position: absolute;
  left: -999em;
}

#nav li:hover ul {
  left: auto;
}

The way the submenus are hidden and then brought into view is accomplished by absolute positioning. In the normal state, a large negative left position (left: -999em;) hides the submenus offscreen. They are actually there the whole time (and if you turned off styles you’d see them below the first level menu items), they’re just removed past the viewport area. On hover over the first-level menu items, the left position is reset to left: auto; which returns the submenus to their normal position, i.e. viewable on screen.

These are just a few examples of ways in which you could use absolute positioning. There are many more and some do involve moving whole chunks of content around (often used when you want the order of your content in the source to appear differently than it does on screen), but I hope the examples provided will give you an idea of the concepts involved in working with absolute positioning successfully.