Style tables with CSS

I don’t deal too much with tables. Not because I don’t want to but because clients hardly ever want to use them. My guess is that they are too hard to create with todays WYSIWYG editors, and therefore get left out. It happens though that I have one or two static tables I need to style, and then I get to use a couple of my tricks.

All of the examples below work across browsers. Including IE6.

Add a gradient to your cells

One easy way to make tables look better is to add a subtle gradient to the cells. That’s easy to do. But make sure you also set a background color with one of the edge colors from the gradient, and use the top or bottom keyword. You never know the height of your cells when people zoom the text.

td {
background: #2B2B3C url(item_gradient.gif) repeat-x bottom;

Remove the space between the cells with CSS

When designing tables you rarely want the ugly double border between two cells that appear when you set a border on td. Neither do you want the space in between them… Many believe the only way to remove that space is to use the cellspacing and cellpadding attributes in HTML. You don’t:

table {
border-collapse: collapse;
td {
border: 1px solid silver;

See? No ugly HTML attributes needed.

Obey the set width

Many of you have probably seen tables that do not stay within the width you have set on them. It can be long words or sometimes URLs that are wider than what can fit. By default, the browser puts content before style, and therefore expands the table to show the content. But what many don’t know is that you can change them to always obey the set width:

table {
table-layout: fixed;
width: 100px;

Easy, and now the table will be 100px, no matter what.

Styling columns

Sometimes you want to style some columns differently than all other cells, and I’ve seen that most people add a special class to each of the cells in that column. Wouldn’t it be nice if there was a way to just specify the class once? There is!

Header 1 Header 2
Cell 1 Cell 2

col.second {
width: 100px:

Convenient isn’t it? There’s one thing you should know though… The col attribute only allows four attributes: Border, Background, Width, and Visibility. What the heck? Well, there is performance issues with implementing more complex things so W3C decided not to include it. So what if you need to set, say, text-align on a column? You can be clever:

col.second {
text-align: right;
td:first-child + td {
text-align: right;

The above works because IE allows setting more properties on columns than the spec allows (Hixie explains it well). Firefox on the other hand, ignores the set text-align, but instead allows you to use a sibling selector to select the “second td after the first one” (you can add another “+ td” to select the third one, and so on…). Voilá! Cross browser column specification.

That’s all for now, did you know all of them?

18 responses to “Style tables with CSS

  1. Good write-up.

    As we’ve seen in a mutual project, border-collapsing doesn’t work properly in Firefox, when the table has a 100% width and a border itself

  2. @Robert Nyman: I remember the case of the disappearing outer border. But there were many more variables to fuck things up there. If you get to that point, then sure, use your cellspacing attribute :)

  3. The trick with using COL has crossed my mind now and then for about two years now, but I never tried it – as you said, one does not use tables that much.

    Nice to see that CSS does as one can expect it to. :)

    Really good writeup anyways. I will definitely show this to my collegues – since they tend to classitis all tables.

  4. Err… :-\ I was reading the pre-updated. But after the update it still looks buggy! :) :P

  5. Really… I don’t want to be dull, but what I see is ‘border-collape’…

    Or you’re missing a ‘s’ or you want mokeys in your codes! :) :P

    Have a nice day.
    Peace & Love


  6. OK. now the code section 2 (“Remove the space between the cells with CSS”) rightly states:
    table { border-collapse: collapse; }

  7. I’m working on some table -based graphs at the moment and am styling them with CSS. Thanks for this article, it couldn’t have come at a better time.

  8. I was looking for the gradient background stuff for custom WordPress theme, the client needs the theme colors to be changed anytime.

    I am sure this is gonna help me a lot. Will give it a try.

    Thanks for sharing..

  9. For me, tables are not bad, Its better to use custom CCS layout instead of this, tables are good for tabular data. They are not built for structuring the layout.

  10. I’ve read Hixie’s interesting page.
    But it’s still not clear why width or border properties are different from text-align!
    Whatever the CSS mechanism does with the former ones, can be done for the latter. It sounds straightforward to my ears (but maybe I’m wrong).
    In my opinion, it makes perfect sense to define table styles either by rows or by columns accordingly to the specific table.
    In general, if you have items on the rows and their properties on the columns, styling by column makes better sense.

    Your suggested workaround is … just a workaround. A working one, indeed.
    But column styles should not rely on column ordering! And your solution does.

  11. @Vincenzo Romano: I agree that it’s not a perfect solution, but it’s the only one that works. I think hixie’s explaination simply is that width and border affects other cells in the table, so it you set column widths calculating table cell widths gets really hairy. That’s my guess anyhow.

  12. Hey thanks for the CSS table tips. There were a couple of techniques I never knew about. Like the table-layout: fixed; I always wonder how you can make tables obey your width element. Also great trick with the tag.

  13. Thanks, I’ve used this on a site I’m working on at the moment. Great stuff!!

Comments are closed.