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
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 & 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.
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
- Throwing Tables Out the Window - [StopDesign] Microsoft's site without tables
- Box Model Hack - [Tantek] CSS hacks for specific browsers
- Bring on the tables - [456 Berea St] tables for data
- CSS Zen Garden - [MezzoBlue] one html, many designs
- Three Column Layouts - [Glish] using css for layouts