Moving from Tables to CSS

3 steps to CSS heaven

Following on from a recent post over on the blog, I thought I'd share some ideas on moving from tables based layouts to pure CSS based ones.

If you're here it probably means you already understand the benefits of pure CSS layout: faster download times, improved accessibility and search engine optimisation for example. There are already lots of tutorials on CSS based design, but what most of these articles don't tackle is developing a practical learning process of moving carefully from tables to CSS design.

In this article I'm not going to concentrate on CSS code directly, instead I'm going to show a stepped approach to moving existing sites from tables to CSS, and for starting to include more CSS based design into your workflow.

Why? Because I still think many people find learning to build CSS layout sites from scratch difficult. There's a steep learning curve associated with CSS design, much more so than tables, and getting consistent results across different browsers is tricky, even for the more experienced.

Developing a strategy that allows you to gradually introduce more CSS based design into your development process can ease the frustration, while still allowing you to progress towards better design practices.

Lets take a look at the stages in the process:

Moving from Tables to CSS based design

You might want to tackle each of these stages by redesigning an existing tables based site in a number of steps, or you might want to try them out over a succession of new websites.

Step 1: Moving from Tables to CSS styled Tables

Take a look at the following table:

Banner
Side Nav Content

Now lets take a look at some traditional HTML that might have been used to create this monstrosity:

<table align="center" cellpadding="10" cellspacing="1" border="0" bgcolor="#000000" width="80%" height="200">
<tr>
<td height="60px" valign="middle" colspan="2" bgcolor="#ffffff">Banner</td>
</tr>
<tr>
<td width="30%" valign="top" bgcolor="#ffffff">Side Nav </td>
<td valign="top" bgcolor="#ffffff">Content</td>
</tr>
</table>

How we can improve this by using a CSS styled Table? First the HTML:

<table id="main" cellspacing="1">
<tr>
<td id="banner" >Banner</td>
</tr>
<tr>
<td id="side">Side Nav </td>
<td>Content</td>
</tr>
</table>

And now the CSS:

#main {
width:80%;
height:200px;
background:#000;
margin:auto;
}

#main td{
background:#fff;
vertical-align:top;
padding:10px;
}

#banner {
height:60px;
vertical-align:top;
}

#side {
width:30%
}

So what did we do?

  • Gave Table and individual Cells an id
  • Moved all widths and heights into CSS
  • Moved all text alignments into CSS
  • Controlled background colours with CSS
  • Aligned Table in the centre using margin:auto

The results are exactly the same, but there are significant advantages to using the CSS styled Table. These are:

  • Reduced Markup: The amount of HTML now used is considerably reduced, improving download time and SEO.
  • Valid Markup: The code will now validate correctly as all deprecated attributes have been removed from the HTML.
  • Site Consistency: Because the table is now styled by an external CSS there is a better chance for consistency across a website where all tables link to this one CSS file. This means no more changing column widths going from page to page.

Step 2: Table layout and CSS layout co-existence

The first step in moving from Tables based layout to CSS based layout is a relatively easy one, and should be managed without any problems. The next step introduces us to the beginnings of CSS layout.

Take a look at the following example:

Company address
contact details
email etc
example logo

Company Name

  • Link 1
  • link 2
  • link 3
  • link 4

catLorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sed elit aliquet velit volutpat laoreet. Pellentesque lacus. Curabitur eget arcu.

rabbitMaecenas scelerisque, odio eget ornare dapibus, tortor quam volutpat purus, et ultrices enim dui id nulla

Now traditionally you might have considered achieving this result through a set of nested tables like the ones below:

example logo

Company Name

Company address
contact details
email etc
Link 1
Link 2
Link 3
Link 4
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sed elit aliquet velit volutpat laoreet. Pellentesque lacus. Curabitur eget arcu. cat
rabbit Maecenas scelerisque, odio eget ornare dapibus, tortor quam volutpat purus, et ultrices enim dui id nulla

However, using a bit of CSS positioning we can easily eliminate the nested tables, lightening our code and improving accessibility.

The trick is using floats. Floats basically move elements to one side while still allowing the other content to wrap around it, and they are perfect for the example above.

Take the banner for example. If we first assign an id to the top table cell then float the logo graphic to the left and the <address> to the right we can remove the need for a nested table altogether.

<table border="0" cellpadding="0" cellspacing="1">
<tr>
<td id="banner" colspan="2">
<address>Company address<br />
contact details <br />
email etc</address>
<img src="images/logo.gif" alt="example logo" width="56" height="50" />
<h2>Company Name</h2>
</td>
</tr>
<tr>
<td style="width:30%"><ul id="exlist">
<li>Link 1</li>
<li>link 2</li>
<li>link 3</li>
<li>link 4</li>
</ul></td>
<td> <p><img src="images/cat.gif" width="50" height="50" alt="cat" style="float:right;margin-left:6px" />Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sed elit aliquet velit volutpat laoreet. Pellentesque lacus. Curabitur eget arcu. </p>
<p><img src="images/rabbit.gif" alt="rabbit" width="50" height="50" style="float:left;margin-right:6px"/>Maecenas scelerisque, odio eget ornare dapibus, tortor quam volutpat purus, et ultrices enim dui id nulla</p></td>
</tr>
</table>

And now the CSS:

#banner {height:60px;}
#banner img{float:left;margin-right:15px}
#banner address{float:right}

#exlist{list-style:none}
#exlist li{padding:3px}

The same thing has been done to the main content section, the images of the cat and rabbit have been floated to the right and left removing the need for the nested table there.

The navigation at the side uses a CSS styled list, again removing the need for a nested table. Making small changes like this to your site is an easy way to improve your coding while teaching you some valuable lessons about CSS positioning.

I've not covered floats or styled lists in detail here, but if you need help check out the excellent tutorials at css.maxdesign:

Floatutorial
Listamatic

Step 3: Moving to Pure CSS design

So this is it. The step you've been waiting for. Pure CSS design. Hopefully by now you've picked up some valuable lessons about styling tables and using floats and lists, but you want to go whole 9 yards. Now, I'm not going to cover CSS positioning in depth here, the blog post had links to loads of sites that covered that. Instead I'm going to try and point you in the right direction and warn you about some potential pitfalls.

You've heard the buzz, and you're ready to get stuck into your first build using absolute or relative positioning. Well, you might be off the mark I'm afraid.

I often find people are surprised to learn that modern CSS layouts often have nothing to do with absolute positioning. Why? What's wrong with absolute positioning? It's the whole reason you're reading this article after all. Well, absolute positioning has one major drawback: every time you absolutely position a element with CSS (like a <div> example) you remove it from the document flow. I can sense the blank expressions but bear with me a minute. Lets talk about document flow.

Take the following example:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sed elit aliquet velit volutpat laoreet. Pellentesque lacus. Curabitur eget arcu. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sed elit aliquet velit volutpat laoreet. Pellentesque lacus. Curabitur eget arcu.

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sed elit aliquet velit volutpat laoreet. Pellentesque lacus. Curabitur eget arcu. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sed elit aliquet velit volutpat laoreet. Pellentesque lacus. Curabitur eget arcu.

This is an normal box

Basically we've got a <div> with some text and another <div> inside it. The nested <div> has no positioning on it at all just now.

Lets add some absolute positioning to the nested <div> and see what happens:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sed elit aliquet velit volutpat laoreet. Pellentesque lacus. Curabitur eget arcu. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sed elit aliquet velit volutpat laoreet. Pellentesque lacus. Curabitur eget arcu.

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sed elit aliquet velit volutpat laoreet. Pellentesque lacus. Curabitur eget arcu. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sed elit aliquet velit volutpat laoreet. Pellentesque lacus. Curabitur eget arcu.

This is an absolutely positioned box

See what happens? The absolutely positioned box now sites on top of the text inside the main <div>. This is because the box has been removed from the document flow. Essentially the text doesn't know it exists, and the box just sits on top of it. This is what absolute positioning does.

This can create some problems when designing a page, especially with things like footers. If you think of the way a footer works (it sits underneath everything above it) it has to be part of the document flow. If it doesn't register all elements in the design you'll get bits sitting on top of other bits like in the example above.

It's a common problem, and one you'll see brought up time and time again on CSS forums, and it's all down to the inherit limitations of absolute positioning. The solution: don't use absolute positioning. Instead use margins and padding to control positioning, combined with some sneaky use of floats to solve the footer problem. Like I say, I'm not going over that now, we'd be here all day, but it's worth bearing in mind when you're looking at other tutorials. Most seem to concentrate on absolute positioning when it's often not the best solution.

Note: I'm not saying absolute positioning is always wrong. This site uses it for example, but for many layouts it is unneccessary and can lead to problems.

Ok that's it. By now you should be well on your way to creating sites with CSS layouts. Don't worry if you don't get there overnight. CSS layouts are hard at first, but with the steps above you can take it step by step improving your code with each new attempt. Stick with it though, it's worth it in the long run.

Good luck!