Skip to navigation | Skip to content

Share your knowledge. Make a difference.

How To: Create a Table-less Layout With Dropdown Menus

1 - I can do better 2 - Jury's out 3 - Pretty darn good 4 - Splendiferous 5 - Awesometastic (by 2 people)   Your rating: 1 - I can do better 2 - Jury's out 3 - Pretty darn good 4 - Splendiferous 5 - Awesometastic

Ranked #1347 in Tech & Geek, #34505 overall

Rated G. (Control what you see)

This article describes in detail how to create a table-less layout that includes a menu bar with dropdown functionality. The site created is also compatible with all common browsers.

Using tables to layout web pages has never been the intention of tables, but only in recent time has it become common to require web designers to use more browser friendly methods. Of course, only in recent time has the CSS-support been good enough to avoid the tables without way too much hassle, but how do you do the CSS-layout right?

In this article, we will first see how we can define and describe a layout by using CSS instead of tables, before we take a look on the modern way to implement dropdown menus with almost no JavaScript what so ever.

Check out the demo implementation.

Sketch 

First of all, you need to know how the layout of the page will be. Draw it down on paper. A rough sketch is more than sufficient. This sketch must be clear on what the different sections of the page is. For example, a common layout can consist of header, navigation, main content, a small column for ads or list content, and footer.

In my sketch I've chosen a static width, centered layout with the mentioned sections where I have a misc content column on the right and a horizontal navigation bar. It's nothing fancy, but clean and clear.

Structure 

Let's see how we structure the above layout with (X)HTML.

<html>
(...)
<body>

  <div id="page_wrapper">
    <div id="header"></div>
    <div id="nav"></div>
    <div id="right_column"></div>
    <div id="border_wrapper">
      <div id="content"></div>
    </div>
    <div id="footer"></div>
  </div>

</body>
</html>

Notice how simple the html is for this layout. This is the power of using CSS to define layout, versus tables which would require either nesting or some colspan logic.

All the visual-specific stuff will now be separated from the code that specifies the sections, and this enables us to easily modify the look of a page without even touching the html (which on static sites could involve updating dozens of html-files).

You might wonder what the border wrapper is for, but we'll get to that later.

Relevant Reading 

The Zen of CSS Design: Visual Enlightenment for the Web (Voices That Matter)

Avg. Customer Rating: Amazon Rating

Amazon Price: $29.69 (as of 10/15/2008)
List Price: $44.99

Head First HTML with CSS & XHTML

Avg. Customer Rating: Amazon Rating

Amazon Price: $26.39 (as of 10/15/2008)
List Price: $39.99

CSS Mastery: Advanced Web Standards Solutions

Avg. Customer Rating: Amazon Rating

Amazon Price: $23.09 (as of 10/15/2008)
List Price: $34.99

Style 

Now, for the CSS, we begin with some of the general attributes:

body {
  margin: 10px;

  font-family: arial, verdana;
  font-size: 10pt;

  color: #666;
  background-color: white;
}
h1, h2, h3, h4, h5, h6 {
  color: #69c;

  margin: 0;
  padding: .5em 15px;
}
p {
  margin: 0;
  padding: 0 15px 1em;
}

There's nothing special here. I just set the standard for how large the text should be (which affects the em-unit that I use to define font size later), the default font, and a softer text color. I set the default header color to a nice blue, and force the margin for both headers and paragraphs to zero and top/bottom padding to be defined by the font size. I set all these explicitly as different browsers tend to have different defaults for these values, and I want to achieve a consistent look as is possible.

Layout 

Now for the actual layout, we start with the page wrapper:

#page_wrapper {
  margin: 0 auto;
  width: 760px;

  border: 1px solid #ccc;
}

The left and right margins are set to auto. This is the correct way of centering a block, but for this to work in all browsers you must remember to specify the doctype-tag correctly. I currently use XHTML 1.0 Transitional, as it seems to be both flexible and widely supported. The tag for XHTML 1.0 Transitional looks like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

I set the width of the page to 760 pixels (always define the unit (e.g. px), unless the value is 0), as this will display correctly on 800x600-screens, and it makes the paragraphs suitably wide for reading.

Note: The design of this page is static width. If you prefer dynamic width just remove the width-attribute from #page_wrapper. The rest of the design will not be broken. You can also specify max-width and min-width to keep some control in the browsers that support these attributes (IE6 does not).

#header {
  width: auto;

  letter-spacing: .6em;
  text-align: center;
  padding: 2px 0;

  background-color: white;
}
#header h1 {
  font-size: 2.2em;
}

This defines the whole look of the header. It gets the blue color from the other headers, and I added some extra letter spacing for a more important feel. Notice that I plan to use the h1-tag for the header text, as this tells both non-visual browsers and search engines that this text is important. You can also define styles for the h2-tag this way, if you want to have a subtitle in the header.

More Layout 

#nav {
  width: auto;
  height: 22px;

  border: 1px solid #ccc;
  border-width: 2px 1px;

  background-color: #8ac;
}

This defines the look of the navigation bar. We will get back to how we define the dropdown menus later.

#border_wrapper {
  border-right: 300px solid #eee;
}

A right border of 300 pixels? Now that seems a bit much. This is the trick I use to set the background of the right column, without having to use images. This, combined with the right column style, ensures that the background of the right column always covers from top to bottom, which makes it really look like a column, and not a box in the top-right corner.

#right_column {
  width: 300px;
  background-color: #eee;
  padding: 15px 0;
  float: right;
}
#right_column h1, #right_column h2, #right_column h3, #right_column h4, #right_column h5, #right_column h6 {
  color: #999;
}

As you see, I have set float to right. This positions the right column exactly over the border of border wrapper. I also set the background color to the same as the 300 pixel border, or the illusion of a right column from top to bottom would be broken.

#content {
  width: auto;
  padding: 15px 0;
}

Because of the 300 pixel border, the content will not flow in below the right column content, and we can all be happy.

#footer {
  clear: both;
  width: auto;
  padding: 3px;
  text-align: center;

  border: 1px solid #ccc;
  border-top-width: 2px;

  background-color: #8ac;
  color: white;
}

This is all just to match the look with the look of the navigation bar.

Dropdown Menu Structure 

Now, for the dropdown menu, let us write some code to define the menu structure:

<div id="nav">
  <ul>
    <li><a href="">Link 1</a></li>
    <li><a href="">Link 2</a>
      <ul>
        <li><a href="">Sub link 1</a></li>
        <li><a href="">Sub link 2</a></li>
      </ul>
    </li>
  </ul>
</div>

This defines a menu with two links, where link 2 has two sub links. Tip: If you experience that the menu items is spaced wider apart in some browsers than others, try to remove the whitespace between the list elements, as this can add extra padding sometimes (usually this is avoided if you specify the doctype-tag correctly).

Making the Dropdown Menu Functional 

Firstly, we will just assume that all browsers support the :hover pseudo-class for all elements. Utilizing this and the parent-child feature of CSS, we can design a clever dropdown menu with no advanced or confusing JavaScript involved. Here is the CSS with some explaining comments, and some warnings about things you might think will work, but won't (on all browsers):

/* Affecting all ul and li elements under navigation */
#nav ul {
  margin: 0;
  padding: 0;

  list-style: none;
}
#nav li {
  margin: 0;
  padding: 0;

  float: left;

  border-right: 2px solid #ccc;
}
/* Affecting only ul and li elements in sub menus */
#nav li ul li {
  border-right: none;
  border-top: 2px solid #ccc;
}
#nav li ul {
  width: 100px;

  position: absolute;
  /*
   * Trick that keeps the sub menus that shouldn't be visible, invisible.
   * Don't try and use display: none; instead, as this may not result in
   * the desired effect in all browsers.
   */
  left: -999em;
  top: 0; /* Don't set to auto, it will break in some browsers. */
}
/* This automatically places the sub menu where it should be; below the parent menu item */
#nav li:hover ul {
  left: auto;
  top: auto;
}

That was a decent amount of CSS, but not nearly as much as the JavaScript equivalent would be. I will not go more into detail about what this code does, other than that it does show the sub menus when the user hovers the mouse over the parent element. This code is sufficient for one level of sub menus only. More levels can be added by simply extending this CSS-code.

Designing the Links 

Defining the look of the links is done by the following CSS:

#nav a:link, #nav a:visited, #nav a:active {
  display: block;

  width: 100px;
  margin: 0;
  padding: 3px 10px;

  text-decoration: none;

  background-color: #58c;
  color: white;
}
#nav a:hover {
  background-color: #69d;
}

This makes the menu items nice buttons that changes color when hovered. Also, the whole button is clickable, not just the text, which is a nice feature.

Relevant Reading 

Stylin' with CSS: A Designer's Guide (VOICES)

Avg. Customer Rating: Amazon Rating

Amazon Price: $23.09 (as of 10/15/2008)

Prioritizing Web Usability (VOICES)

Avg. Customer Rating: Amazon Rating

Amazon Price: $31.50 (as of 10/15/2008)

The Suckerfish Solution 

Now, as some of you might have noticed, the dropdown menus will not work in IE6 (and all other browsers that doesn't support :hover). Luckily, this problem has been solved already. All you need is a tiny JavaScript and a small addition in the CSS, and we're good to go. The JavaScript is known as Suckerfish, and the one I prefer can be found at HTML Dog. The required changes to the CSS is an addition to all the :hover elements, as follows:

#nav li:hover ul {
...is changed to...
#nav li:hover ul, #nav li.sfhover ul {

...and that's it! If you include the Suckerfish-script, the dropdown menus should now work on IE6 as well (and even some older versions of IE).

Conclusion 

There it is. You should now have a good idea of how to start creating your own table-less layout with dropdown menus. You will probably face some of the many oddities of browsers that makes your site display differently on different browsers, but don't give up (or turn mad, as many do), it is usually possible to work around them, or at least get an acceptable result.

Reader Feedback 

sydneyrite

hey thanks man this could really help with my HREF="basketball-layouts.com">myspace layouts thanks again

Posted April 14, 2008

myevans

Thanks, this works great :)

Posted May 31, 2007

X
Newstead

About Newstead

Experienced web designer and developer (with a weakness for VG Cats) helping you make sites that validate and work on all common browsers.

Newstead's Pages

See all of Newstead's pages