In my last post, I mentioned that I had come up with a way to prevent tables in Internet Explorer 6 and 7 from looking like this. In this post, I'll show you how to do it.

(Disclaimer: This method has been found to break if the a cell has a line break in it or is wrapped to a second line).

First, let's start with an example table:

<table id="example-table">
  <thead>
    <tr><th>First Name</th><th>Last Name</th><th>Client #</th></tr>
  </thead>
  <tbody>
    <tr><td>Joe</td><td>Shmoe</td><td>123451</td></tr>
    <tr><td>Joe</td><td>Shmoe</td><td>123451</td></tr>
    <tr><td>Joe</td><td>Shmoe</td><td>123451</td></tr>
    <tr><td>Joe</td><td>Shmoe</td><td>123451</td></tr>
    <!-- Repeat these many times to make it go to a second page. -->
  </tbody>
</table>

Add a stylesheet like this:

#example-table
{
  border: 1px black solid;
  border-collapse: collapse;
}

#example-table th, #example-table td
{
  border: 1px black solid;
}

If you repeat those rows enough times you can get the graphical glitch mentioned above. Now, to fix it, what we'll do is add a <div> tag to every cell and then make it provide the side borders.

So first, we'll modify the table as follows:

<table id="example-table">
  <thead>
    <tr><th>First Name</th><th>Last Name</th><th>Client #</th></tr>
  </thead>
  <tbody>
    <tr>
      <td><div class="cell">Joe</div></td>
      <td><div class="cell">Shmoe</div></td>
      <td class="last-col"><div class="cell">123451</div></td>
    </tr>    
    <!-- Repeat this many times to make it go to a second page. -->
  </tbody>
</table>

What we've done here is added a <div> to each cell and given these <div>'s a class called cell. This is so we can do stuff to them in our CSS stylesheet. We've also given the last cell in each row the class last-col. This is so we can identify the last column of each row. The reasoning for this will be explained shortly.

Now, as I've said, our goal here is to replace the table-provided vertical borders (the | ones) with the div-provided ones. So we need to modify the stylesheet to reflect that:

#example-table
{
  border-top: 1px black solid;
  border-bottom: 1px black solid;
  border-collapse: collapse;
}

#example-table th, #example-table td
{
  border-top: 1px black solid;
  border-bottom: 1px black solid;
}

There's also an issue of padding. By default, tables are slightly padded, which is fine for most circumstances. However, in this case, padding would be counterproductive, it would prevent the div's border from matching up with the table's border. So that'll have to be changed:

#example-table
{
  border-top: 1px black solid;
  border-bottom: 1px black solid;
  border-collapse: collapse;
}

#example-table th, #example-table td
{
  border-top: 1px black solid;
  border-bottom: 1px black solid;
  padding: 0;
}

Time for some div styling. Since the div is our new cell, we need to style it as such. First thing, let's make the div provide us with sides. Now, we could do something like border-left: 1px black solid; border-right: 1px black solid;. This would look fine, except that all the vertical borders in the middle of the table would 2 pixels wide (think about it). So, instead, we'll make all the div cells provide borders on the left side, except for the last column, which'll provide borders on both sides (hence the purpose of the last-col class).

div.cell
{
  border-left: 1px black solid;
}

#example-table .last-col div.cell
{
  border-right: 1px black solid;
}

We also need to add back the padding we stripped out from the table td tags:

div.cell
{
  border-left: 1px black solid;
  padding: 4px;
}

#example-table .last-col div.cell
{
  border-right: 1px black solid;
}

And there you have it. Now when you load up print preview, your tables should look pretty. Here's the final stylesheet in case you got lost:

/* So the headers will display on every page. */
thead { display: table-header-group; }

/* Make table only provides vertical border. */
#example-table
{
  border-top: 1px black solid;
  border-bottom: 1px black solid;
  border-collapse: collapse;
}

/* 
 * Make header and normal cells only show top and bottom border,
 * and remove all padding so the div lines will match up with the table.
 */
#example-table th, #example-table td
{
  border-top: 1px black solid;
  border-bottom: 1px black solid;
  padding: 0;
}

/* Make the div cell only provide the left border, and simulate table padding. */
div.cell
{
  border-left: 1px black solid;
  padding: 4px;
}

/* Provide the right border in the last column. */
#example-table .last-col div.cell
{
  border-right: 1px black solid;
}