Saying goodbye to Tables

In the early days of HTML, there was little choice but to use Tables for laying out a web page. Although they were originally intended for presenting tabular data, the main use for Table was layout. Now that we have better options, why continue to mix presentation detail in with content?

Why Change?

It's not uncommon to see sites littered with code like:

<table border="0" cellpadding="0" cellspacing="0" width="771" height="15" bgcolor="#eeeeee"> <tr><td valign="top"><img src="images/spacer.gif" width="14" height="1" alt=""></td> <td><font color="red"><b>News</b></font></td></tr>...

Moving the style and layout detail to CSS, the HTML can be as simple as:

<div id="newscol"><h2>News</h2>...

What does the above Table code mean? A few years from now, how easy will it be to maintain? How difficult will it be for another webmaster next week? Moving away from Tables and using Divs produces many benefits.

Bandwidth
pages shrink because layout is moved to a shared css file
Maintenance
shorter, simpler page code is easier to maintain
Flexibility
design changes means editing a css file, not all html pages
Accessibility
extra tables can confuse software for the handicapped
Better Searches
sites are weighed according to content, not page size
Proper use
tables are intended to display tabular data

How?

Instead of using Tables to separate content into columns, use Divs. Use a Div for each column, define width and float settings using css. Take a look at the source for this common, two column layout using both Tables and the Div equivalent. In this example another Div is acting as a container to hold both Div columns, read the caveat below to find out why. Glish has more layouts.

Example

Two column example using Tables

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip.

Two column example using css & Divs

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip.

Source

<style>
.container {
	width: 300px;
	background-color: #eee;
	/* trick to extend bg colour around floating cols */
	border-bottom: 1px solid #ccc;
}

#col1, #col2 {
	width: 140px;
	float: left;
}

#col2 {float: right;}

.endfloats {clear: both;}

.gap, .content {margin-top: 6px;}
</style>


<h3>Two column example using Tables</h3>

<table width="300" cellpadding="0" cellspacing="0" bgcolor="#eeeeee">
 <tr>
  <td width="140" valign="top">
	Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
  </td>
  <td width="20">
	<img src="images/spacer.gif" height="1" width="20"/>
  </td>
  <td width="140">
	Ut wisi enim ad minim veniam, quis nostrud exerci tation
	ullamcorper suscipit lobortis nisl ut aliquip.
  </td>
 </tr>
</table>

<br/>

<h3>Two column example using css &amp; Divs</h3>

<div class="container">
 <div id="col1">
	Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
 </div>
 <div id="col2">
	Ut wisi enim ad minim veniam, quis nostrud exerci tation
	ullamcorper suscipit lobortis nisl ut aliquip.
 </div>
 <div class="endfloats">
 </div>
</div>

Caveat

Unfortunately browsers will take the same html & css and produce different results. The most common problem is that a page element (or div) will vary in width depending on the browser. Some browsers add padding, margin and border size to the width, some don't.

Solutions

Taking advantage of quirks within the CSS interpreter of each Browser, a css hack can force different behavior depending on the browser. This approach relies on browsers reading the css a certain way, and computing width a certain way. Unfortunately, this css code does not always validate.

Another solution is to nest DIVs. This method uses the outer DIV to define the element width, and the inner DIV to define padding, border and margin. Because it does not rely on any browser quirks, it will always work.

Example

Div examples

Settings border: 3 pixels, padding: 10 pixels.

Nested divs - always 300 wide
Single div - width depends on browser
Simulated single div Explorer 6.0.2 Win
Simulated single div Opera 7.50 Win
Simulated single div Firefox 1.0.3 Win

Source

<style>
.container, .plain {width: 300px;}

.content, .plain, .simulated {
	border: 3px solid gray;
	padding: 10px;
	background-color: #c99;
}

.plain {background-color: #999;}

.simulated {background-color: #699;}

.plain, .container {margin-top: 6px;}
</style>


<h3>Div examples</h3>

<p>
<strong>Settings</strong> border: 3 pixels, padding: 10 pixels.
</p>

<div class="container">
 <div class="content">
  Nested divs - always 300 wide
 </div>
</div>

<div class="plain">
 Single div - width depends on browser
</div>

<div class="container">
 <div class="simulated">
  Simulated single div Explorer 6.0.2 Win
 </div>
</div>

<div class="container">
 <div class="simulated">
  Simulated single div Opera 7.50 Win
 </div>
</div>

<div class="container" style="width: 326px;">
 <div class="simulated">
  Simulated single div Firefox 1.0.3 Win
 </div>
</div>

Resources