Setting Table Styles with CSS

While web design and CSS purists criticize the abuse of tables, there are still many circumstances in which they provide a useful (and predictable!) display of your content. This CSS tutorial will show you how you can style the individual rows and columns of your tables - down to the individual trs and tds - when you actually need to display tabular data and give that display some visual appeal and make it more legible to users. Thanks to the child selector pseudo classes in CSS 3, you can easily style tables completely within your stylesheet without requiring any inline styles or complicated HTML or CSS mark-up.

Styling A Table Column With CSS

So let's begin with something that seems a little tricky: setting a style on a table column. The HTML mark-up for tables are structured in rows, so you need to reverse your thinking a bit when trying to style in columns. The key is to think in terms of the parent and child relationships, with the trs being the parent and the tds being the children when creating your CSS rules. In the example below:

Click Here to see the actual HTML for the table above.

The CSS required to style the first column is the pseudo-class "first-child". By using the selector:

table tr td:first-child { background-color:#e0e0e0; }

I am selecting the first td following a tr, which effectively controls the first column. I could also use:

table tr td:nth-child(3) td { background-color:#e0e0e0; }

to control any column I choose by selecting the appropriate value for "nth-child".

Styling a Table Row with CSS

Similarly, I could control any selected row by selecting the "nth-child" tr of my table. Let's style the second row. On a good day, we'd use the thead element to define the table heading, but since I'm lazy, I'm creating these tables with JavaScript just to avoid coding them one-by-one, and I didn't bother to add the code for a header. So, all I'm left with is using CSS to control the tds in the second tr with:

table tr:nth-child(2) td { background-color:lightgreen; }

resulting in:

Advanced Styling With CSS3 Selectors

But what about when you need something more complex, like setting the styles on both rows and columns. Let's try something more challenging. How about a kind of invoice where we have product information and invoice totals to deal with, as well as rows with differring numbers of columns, and potentially differring numbers of rows. The table below shows just such a table. This time, I created everything in discrete HTML so you can examine the source code with "View Source". There are still no inline 'style' attributes here. In fact, the only internal elements with any attributes are the tds that required a 'colspan'. Simple "nth-child" psuedo-classes alone won't be enough. We'll also have to use an attribute selector.

Item # Description Qty. Unit Cost Total
18-0045 Universal Widget 26 $.99 $25.74
18-0047 Large Universal Widget 18 $1.99 $35.82
SubTotal: $61.56
Shipping: $11.29
Total: $72.85

Click Here to see the actual HTML for the table above.

#invoice tr:first-child td { background-color:#008; color:#fff; font-weight:bold; }
#invoice tr td:nth-child(4), #invoice tr td:nth-child(5) { text-align:right; }
#invoice tr:first-child td:nth-child(4), #invoice tr:first-child td:nth-child(5) { text-align:center; }
#invoice tr td:last-child { font-weight:bold; }
#invoice tr td:nth-child(3) { text-align:center; }
#invoice tr td[colspan] { font-weight:bold; }
#invoice tr td[colspan] { text-align:right; }
#invoice tr td[colspan] + td { color:purple; text-align:right; }
#invoice tr:nth-last-child(2) td[colspan] + td { color:#000; }

We've done a lot of CSS work here without any inline styles. The first row has a navy blue background with white, bold text. The text in the "Qty." column is center aligned, and the numeric columns are right aligned. And the last column also has all bold text. The tricky part was setting a separate style for the rows whose first td used a 'colspan' attribute, and then selectively styling the following td as well. Then, just for drill, I made the 'Subtotal' and 'Total' values purple and made the 'Shipping' value remain black. This is much more convoluted styling than you would normally use, since it requires overriding a previous rule. I just wanted to demonstrate the power of these new CSS3 selectors.

CSS Table Borders

Old codgers like me started out by relying on the 'border' attribute for the table tag. But best practice for HTML and CSS is to do all of the styling with CSS and use HTML only for structure. That's fine for most elements, but tables have many quirks that mean you have to pay a little extra attention to styling them. And that's particularly true when it comes to borders, thanks to the row and column structures you must rely upon.

If you simply set the border width on all of the td tags, you'll get a mix of single and double-width borders. So you have to remember how tables are rendered by the browser using rows and columns. This means setting borders only on the top and left sides of trs and the bottom and right sides of tds. That will give you a uniform border on all of the table cells. But you'll notice that the outside borders all of the tables on this page are double-thick. Doing that required using psuedo-selectors again, as in:

.rdTable { border-collapse:collapse; width:80%; margin:2px auto; }
.rdTable tr { border-style:solid; border-color:#00f; border-width:1px 0 0 2px; }
.rdTable td { padding:2px 4px; border-style:solid; border-color:#00f; border-width:0 1px 1px 0; }
.rdTable tr:first-child { border-top-width:2px; }
.rdTable tr:last-child td { border-bottom-width:2px; }
.rdTable tr td:last-child { border-right-width:2px; }


For many website designers, the benefit of doing all of the styling in the stylesheet is that scripts that generate the HTML code for such tasks are relieved of the burden of incorporating inline styles, which makes them much easier (and cheaper!) to maintain.

Browser support for the methods described here is excellent. As usual, it's only the older versions of Internet Explorer (IE 8 and below) that don't support much of CSS 3, but fortunately those browsers make up a small percentage of users and are bound to fade into true insignificance in the next year or two. has a great CSS tutorial titled, The 30 CSS Selectors You Must Memorize. I relied on it heavily in creating this page and you'll find an explanation for all of the special selectors I used here. So, thankfully, you don't have to actually memorize all of the information they have on CSS selectors. Just check it out online! You can get very fine CSS style control over your web pages by understanding these advanced selectors.

This page was last modified on October 11, 2017

Copyright © 2005-2018 by Richard L. Trethewey - Rainbo Design Minneapolis. It's not that I think this is such an earth-shatteringly great presentation, but if you want to copy it, I'd appreciate it if you would ask for permission. I've been working with computers for over 30 years now, and one phrase keeps popping into my head - "I hate it when it's right!" And laptops and smartphones are no better.

Looking for more website design information? See my Sitemap!

  Share This Page!  
Still Have Questions? 
Talk To Me! Click Here!