One-pixel table border with CSS

Problem

I want to have a one-pixel one-color solid border around a table and its cells. Adding border="1" to the table tag isn’t suitable, because it looks horrific in most of the browsers.

Solution with HTML only

Back in the old days we used to use just HTML to create a one-pixel border. Some people even used 1×1 pixel transparent gifs, but let’s not go into that. The easiest way to achieve the border was to use nested tables: outer table that provides the border color and inner table that holds the content.

Here’s an example:

Cell 1 Cell 2
Cell 3 Cell 4

Looks pretty fine, doesn’t it? However, let’s look into the code:

<table border="0" cellspacing="0" cellpadding="0">
<tr>
    <td bgcolor="#660000">

    <table border="0" cellspacing="1" cellpadding="4">
    <tr>
        <td bgcolor="#FFFFCC">Cell 1</td>
        <td bgcolor="#FFFFCC">Cell 2</td>
    </tr>
    <tr>
        <td bgcolor="#FFFFCC">Cell 3</td>
        <td bgcolor="#FFFFCC">Cell 4</td>
    </tr>
    </table>

    </td>
</tr>
</table>

The outer table is very simple. Its bordercellspacing and cellpadding are all set to zero. It has only one cell whose background color is the one you want your border to have. The inner table has cellspacing of one pixel and thus the outer table’s background color is displayed around the inner table and between its cells.

The biggest downside of this approach is that we must have two HTML tables to display one table of data. Also, maintaining the code is difficult, as all the table cells must separately contain the background color attribute. Of course, with a little bit of CSS, you can move the background color setting to the style sheet.

The nifty solution with CSS

With the magic of CSS, we can clean up the code a lot. Here’s what we get:

Cell 1 Cell 2
Cell 3 Cell 4

Unless you’re using a browser that doesn’t support CSS or a browser that supports it badly, the chances are that the table looks exactly the same as the one before. Again, let’s look into the HTML code:

<table>
<tr>
    <td>Cell 1</td>
    <td>Cell 2</td>
</tr>
<tr>
    <td>Cell 3</td>
    <td>Cell 4</td>
</tr>
</table>

This is all we have. Really. Everything else is hidden in a style sheet. You can easily change the looks of your table without touching the HTML (at least that’s what they say, but anyway…).

Maybe the first thing that comes up to your mind when you start creating a style sheet for a table border is to add a one-pixel border to every table cell. However, that would cause the borders to “duplicate” between the cells. The trick is to let cells to have only the top and right borders and add the bottom and left borders to the table. This way it looks like every cell is surrounded with a border, even though technically this is not the case.

This is how we get there:

table
{
    border-color: #600;
    border-width: 0 0 1px 1px;
    border-style: solid;
}

td
{
    border-color: #600;
    border-width: 1px 1px 0 0;
    border-style: solid;
    margin: 0;
    padding: 4px;
    background-color: #FFC;
}

The table cell style sheet has margin set to zero, just for sure, and padding set to four pixels, like in our HTML example. The background-color is set to our beautiful light yellow.

Unfortunately we’re not there yet. In Internet Explorer, Opera and Safari there are weird-looking spaces between each cell. This is because we haven’t explicitly set the space between each cell to zero. In CSS2, there is an attribute for that called border-spacing, but currently it’s only supported by Safari. However, for IE/Win and Opera we can use the border-collapse attribute which “sets the border model of a table”. It has two alternative values, separate (which is the default) and collapse. We’ll go for collapse.

The only culprit after this is IE/Mac which supports neither of these CSS attributes. If you want that your table is displayed correctly in IE/Mac, you must change the tabletag in your HTML code so that it has the parameter cellspacing="0". We have left it out of the final code.

To make the CSS code easier to maintain, we can first set the border color for both table and td and then set the differing part separately. If you later want to change the border color, you only need to change it in one place.

Here is our final code:

<style type="text/css">
/* <![CDATA[ */

table, td
{
    border-color: #600;
    border-style: solid;
}

table
{
    border-width: 0 0 1px 1px;
    border-spacing: 0;
    border-collapse: collapse;
}

td
{
    margin: 0;
    padding: 4px;
    border-width: 1px 1px 0 0;
    background-color: #FFC;
}

/* ]]> */
</style>

<table>
<tr>
    <td>Cell 1</td>
    <td>Cell 2</td>
</tr>
<tr>
    <td>Cell 3</td>
    <td>Cell 4</td>
</tr>
</table>
This entry was posted in Web-Design and tagged , , , , , , , , , , , , , , , , , , . Bookmark the permalink.