Due to the shift from tables-based layouts
to structural markup with CSS styling, many Web builders feel that tables have no
place on a modern, standards-based Web page. Actually, nothing could be further
from the truth. The admonition against using tables is confined to their misuse
as a general layout tool, not to the legitimate role of the table tags (<table>,
<tr>, <td>, <th>) as the recommended
way to mark up tabular matter. There is still no better way to create columns and
rows of data such as price lists, budget spreadsheets, and the like.

Even when designers use HTML tables appropriately,
the table tags traditionally include a lot of inline formatting attributes to specify
column widths, cell borders, cell padding, background colors, and more. This is
the opposite of the recommended practice of separating presentation styling from
structural markup.

However, you don’t have to stick with
the traditional practice of embedding formatting attributes in the table markup.
Instead, you can replace almost all the inline attributes of the table tags with
CSS styling.

Table markup the old way

In their traditional implementation,
the HTML table tags can serve as a worst-case example of stylistic formatting embedded
in structural markup. The result is cluttered and repetitious markup that nearly
obscures the content. The following example code produces the very simple table
shown in Figure A.

<table width="400" border="3" cellpadding="5" cellspacing="2">
    <tr align="center" bgcolor="#FFFFCC">
        <td width="150">&nbsp;</td>
    <tr bgcolor="#CCCCCC">
        <td width="150" align="left"><b>January</b></td>
        <td align="right">123</td>
        <td align="right">234</td>
        <td align="right">357</td>
    <tr bgcolor="#CCCCCC">
        <td width="150" align="left"><b>February</b></td>
        <td align="right">135</td>
        <td align="right">246</td>
        <td align="right">381</td>
    <tr bgcolor="#CCCCCC">
        <td width="150" align="left"><b>March</b></td>
        <td align="right">257</td>
        <td align="right">368</td>
        <td align="right">625</td>
    <tr bgcolor="#CCCCCC">
        <td width="150" align="left"><b>Total</b></td>
        <td align="right">515</td>
        <td align="right">848</td>
        <td align="right">1363</td>

Table styling with CSS

The HTML table tags include a long list
of formatting attributes, but that doesn’t mean you have to use them. Instead, you
can use the same CSS styling techniques on tables that you use elsewhere in your
Web pages. Basically, you can style a table as if it were a div,
and table cells as if they were nested divs or paragraphs.

The following example code produces the
table shown in Figure B.
This illustrates how you can move almost all the formatting information out of the
page markup and into a CSS style sheet.

First, here are the CSS styles:

table#sample {
    border: solid #000 3px;
    width: 400px;
table#sample td {
    padding: 5px;
    border: solid #000 1px;
.data {
    color: #000000;
    text-align: right;
    background-color: #CCCCCC;
.toprow {
    font-style: italic;
    text-align: center;
    background-color: #FFFFCC;
.leftcol {
    font-weight: bold;
    text-align: left;
    width: 150px;
    background-color: #CCCCCC;

Next, here’s the markup for the table.
(Removing the formatting attributes from the markup cleans up this simple table
noticeably. The difference is even more striking on a table with heavier formatting.)

<table id="sample" cellspacing="2">
    <tr class="toprow">
        <td class="leftcol">January</td>
        <td class="data">123</td>
        <td class="data">234</td>
        <td class="data">357</td>
        <td class="leftcol">February</td>
        <td class="data">135</td>
        <td class="data">246</td>
        <td class="data">381</td>
        <td class="leftcol">March</td>
        <td class="data">257</td>
        <td class="data">368</td>
        <td class="data">625</td>
        <td class="leftcol">Total</td>
        <td class="data">515</td>
        <td class="data">848</td>
        <td class="data">1363</td>

Note that the CSS starts with rules that
redefine the <table> and <td> tags in a table with the id=”sample”.
This is a simple way to set common attributes that apply throughout the table.

The table#sample style defines the width of the table, its border, and the
background color that shows through the gaps between the cells. The table#sampletd style sets the padding (which
takes the place of the cellpadding attribute) and the border for each cell, but
it applies only to cells within the sample table.

The three class selectors (.data, .toprow,
.leftcol) control the attributes of the table rows/cells with the corresponding
class IDs in the table. All the alignment, font-style, font-weight, and background
color attributes for these cells are now contained in these CSS rules, not in the
page markup.

The only formatting attribute remaining
in the page markup is the cellspacing
attribute of the <table> tag. As far as I know, there is no way to control
that particular table attribute with CSS. Logically, cellspacing seems to correspond
to the margins in the CSS box model, but changing the margin attribute of the table
cells has no effect on cellspacing within a table.

The most important advantage of using
CSS styling on a table is the ability to separate structural markup from presentation
formatting. But once you make the switch to CSS styling for your tables, you’ll
discover that CSS gives you more formatting flexibility as well. For example, CSS
enables you to independently control the style, color, and thickness of the border
on each side of a table cell; whereas, the inline table formatting options provide
only overall color and thickness settings.