Style columns in tables with CSS

How do you style columns in HTML tables without resorting to styling the individual cells?

There doesn’t seem to be an easy answer to this question that will work with most browsers. The method shown here works fine for my requirements but that’s not to say there aren’t better ways of doing this out there.

The requirement I had was for a restaurant that required a table with three columns; the text of the menu item, special colour characters for vegetarian or wheat free dishes,  and the price of the item. The image below shows an example of the menu.

The text column is left aligned text with a width of 85%. The second column is centre aligned with a width of 5%.  The third column with the price has to be horizontally right-aligned, vertically top aligned, with bold text and a width of 10%.

There are several ways of doing this, one approach is to style each cell in the column but the resulting code is not easily changed and can be very tedious for tables with a large number of cells, plus it is going back to using tables for presentation

An alternative approach is to use pure CSS by constructing the table with <div>tags and not using html table markup at all. This works but does result in divitis with loads of nested div tags.

The best solution I’ve found, and no doubt there are others as good or better out there,  is to use the :first-child pseudo-class.  This pseudo-class matches the first occurrence of the specified element within another element. You can request the first cell within each row in the table with the end result being a column.  So the the CSS  style sheet containing:

div.menu_box td:first-child {
width: 85%
}

Would result in the first column of the table having a width of 85% of the enclosing element, in this case the menu_box div.

To select the second column in the table just use the adjacent sibling combinator which is a plus symbol. This will select an element that immediately follows another element with the same parent,  in this case we select a <td> tag that immediately follows another <td> tag when they are both children of the same menu_box div parent.

Adding this to the style sheet results in:

div.menu_box td:first-child {
width: 85%;
}
div.menu_box td:first-child + td {
width: 5%; text-align: center;
}

Following the same pattern, to make the third column right-aligned and bold we just need to add another adjacent sibling plus (+) sign and another td selector to give:

div.menu_box td:first-child {
width: 85%;
}
div.menu_box td:first-child + td {
width: 5%; text-align: center;
}
div.menu_box td:first-child + td  + td {
width: 10%;
text-align: right;
font-weight:800;
vertical-align: top;
}

This works with most modern browsers, but doesn’t work with IE 6 or previous.

That requires some extra CSS (shown in bold below) to make up for the fact that older versions of IE don’t have support the solution outlined above, but does have support for some non-standard attributes in the

tag (which the more modern standard-compliant browsers like FireFox do not support).  So to get something that works correctly with most browsers you have to use two different methods combined as shown below.

div.menu_box col.c1, td:first-child {
width: 85%;
}
div.menu_box col.c2, td:first-child + td {
width: 5%; text-align: center;
vertical-align: top;
}
div.menu_box col.c3, td:first-child + td  + td {
width: 10%;
text-align: right;
font-weight:800;
vertical-align: top;
}

The col.c1, col.c2 and col.c3 selectors are used within a tag in the HTML table as shown below.

&lt;div class="menu_box">
&lt;table border="0">
&lt;colgroup>
  &lt;col class="c1">&lt;/col>
  &lt;col class="c2">&lt;/col>
  &lt;col class="c3">&lt;/col>
&lt;/colgroup>
...table rows and cells go here....
&lt;/table>
&lt;/div>

To test browser compatibility I used the free service at http://browsershots.org where you can test a page and receive images of the page for each platform/browser/version combination.

This entry was posted in Design and tagged , . Bookmark the permalink.

We would love to hear from you so please leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.