Article
Terrific Tables with CSS
The Styling
Before we dive into some practical examples, it’s important to understand which CSS properties we can actually make use of and where we can use them. We’ll look at styles specific to the table element, columns, and captions. After that, we’ll learn how backgrounds are handled. From there on in, it’s all fun—we’ll go through some examples to demonstrate what can be done to bring a little art to the science of tables.
Using the table Element
Several properties are unique to the table element:
- border-collapse
- border-spacing
- empty-cells
The border-collapse property can have a value of either separate or collapse, as demonstrated in Figure 7, below. separate is the default property, but it creates tables that look fairly chunky. Using collapse removes the space between the cells, effectively overriding any cell spacing that may be set in the HTML. This step will make our tables look cleaner, so it’s a good move to start with.
Figure 7. Comparing separate and collapse values of border-collapse property

Issues with Collapsing Borders
Collapsing the border will create issues if you have borders between two cells where each cell has different border styles. A border conflict resolution guide that explains how these conflicts should be resolved is available from the W3C.
When setting the border-spacing property of a table, you can specify either one or two length values. If only one is specified, the value affects the spacing on all sides. If two values are specified, the first specifies the horizontal spacing (left and right of the cell) and the second specifies the vertical spacing (above and below the cell):
table {
border-spacing: 2px 5px;
}
This example adds two pixels of vertical space and five pixels of horizontal space between each cell.
The color that appears in the space is always that of the table background. Setting the row or cell background will never change the colour between the cells.
Our nemesis Internet Explorer, however, doesn’t support the border-spacing property, even in IE7. The only course of action this situation leaves us with is to use the cellspacing attribute in HTML to achieve the same effect as border-spacing.
The empty-cells property has two values: show and hide, the rendering of which can be seen in Figure 8.
This property determines whether a border will be visible on an empty cell; it can be applied to almost any element within a table, such as specific rows or cells. Once again, however, Internet Explorer doesn’t support the empty-cells property.
Figure 8. Values for empty-cells property—show on left and hide on right
Setting Column Styles
The column group elements (colgroup) are unique in that cells don’t actually inherit anything from them. Therefore, there are only four properties that are applicable to colgroup: border, background, width, and visibility. The use of these properties results in inconsistencies across the browsers, as demonstrated in Figure 9, below—so be prepared!
The border property works well in Firefox and Safari. In Opera, applying border to a col element with a span attribute set on it doesn’t apply the border to each column as it does in Firefox or Safari. In Internet Explorer, the border CSS property doesn’t work at all.
Here’s how we go about setting table borders and border-collapse in CSS:
table {
width: 400px;
border-collapse: collapse;
}
#test {
border: 1px solid blue;
}
... and modifying our HTML to disable the border attribute:
<table border="0">
<caption>Growth Chart</caption>
<col width="60%">
<col width="20%" id="test">
<col width="20%">
...
The border-collapse needs to be set to collapse for the border to show in Firefox and Safari.
Figure 9. Comparison of column border rendering between Firefox and Opera
![]()
![]()
The background property is fairly consistent across browsers, but it still has its little quirks. A background image, for example, applied to a column group is set as the background to each column in Opera, but is incorrectly applied to each separate cell in Safari and Internet Explorer. There are also layering issues that only Firefox can cope with sufficiently. With any luck, you’ll never run into these layering issues, but I’ll cover these in a little more detail in the section called “Applying Successful Backgrounds”.
The width property works well in all browsers tested. Keep in mind that when applied to a colgroup, the width affects the size of each column contained within that colgroup. For example, if you set a width of 200 pixels on a column group that contains two columns, then each column is 200 pixels, reaching a total of 400 pixels for the column group.
Finally, visibility is included just for completeness, but Firefox is the only browser that currently supports it. visibility can be set to collapse, which prevents the column from being seen.
Formatting Captions
caption elements can be formatted like most other block elements, including properties like text-align and font-weight. There’s an additional CSS property that can come in very handy, and that’s caption-side. This property can be set to either top or bottom, which will allow the caption to appear either above or below the table respectively. Firefox takes it a step further and supports values of left or right. I hate to sound like a broken record, but good ol’ Internet Explorer doesn’t support caption-side.
Applying Successful Backgrounds
Since we’re talking about backgrounds on columns, let’s delve a little deeper into how backgrounds on tables should work. Essentially, different elements act as layers. Any transparency on one level reveals the background of the level below it. Figure 10 shows a W3C diagram that demonstrates the layering of backgrounds on table elements.
Figure 10. The W3C’s schema of table layers
![]()
However, as you may have noticed with some of the cross-browser issues I mentioned before, most browsers don’t handle backgrounds like the specification suggests. Many actually take any backgrounds specified at the column or row level and simply apply them at the cell level. When using patterned backgrounds, this can prove extremely frustrating—any repeating patterns fail to line up. Playing with the opacity at the cell level also reveals how badly Safari, Opera, and Internet Explorer get it wrong. As an example, have a look at Figure 11, which demonstrates a background being applied to a table row. Albert displays correctly in Firefox, but he’s in real trouble when displayed in Internet Explorer.
Figure 11. td background comparison between Firefox and Internet Explorer


Unfortunately, table usage just isn’t as popular as it used to be, so we’ll most likely be waiting a very long time for this problem to be rectified in the rest of the browsers.
Luckily, the application of a background on the table element does work consistently. The background should tile properly across the entire table and behave exactly as it should. Let’s give this application a shot, and see whether Albert can avoid being fragmented when he encounters the rigors of being displayed in Internet Explorer.
If our table and columns were of a fixed width, we could actually get around the cell background issues by offsetting the background for each column. It’s a tedious task, but it’s well worth it, so let’s dive in! Here’s an example to demonstrate this approach:
Example 5. background-position.html (excerpt)
table {
width: 223px;
}
td {
background: red url(images/albert.jpg) repeat 0 0;
height: 200px;
}
td.col1 {
width: 90px;
}
td.col2 {
background-position: -90px 0;
width: 43px;
}
td.col3 {
background-position: -133px 0;
width: 90px;
}
Each column after the first is simply shifted over by the width of the previous cells. The first column doesn’t need to be shifted, whereas the second requires shifting over the width of the first column. Finally, the third column background has to be shifted over the total width of the first two columns. Figure 12 shows Albert in Internet Explorer again, but with the background shifted within each cell—he’s much happier.
Figure 12. Resolved Internet Explorer example

Well, that’s all, folks. For the minute, anyway. This understanding of column, caption, and background styles set us up well for that roller-coaster ride—now it’s time for us to look at some practical applications of all the styling we’ve learned!