Designing Tables for Usability
What is more delightful than something that is usable? i wouldn’t appreciate anything, no matter how slick, that pisses me off by being a pain in the ass. Therefore being usable is being beautiful.
With the css-based, table-less layout fad going on for the past few years, tables have somehow become something “taboo” for some designers and have not gotten the attention they deserve. Tables are used for representing data in a matrix, with their relations arranged in rows and columns. Tables can be visual and also conceptual, i.e. database tables. In this article, I will show you how visual tables can be made better and more usable, with code samples which can be easily implemented on an existing site. I will discuss the visual and usability aspect of designing tables and will try to use simplified code for clarity. For more information on improving the accessibility of tables, which this article will not cover, check out this great article.
Objectives
We want to achieve tables which are more scannable, with data that is easily findable, more aesthetically-pleasing and also easier to style using CSS.
Semantic Table HTML Markup
Here we have a basic table.
| Color | Size | Rarity | Price/100 grams | |
|---|---|---|---|---|
| Golden Grapes | Golden Purple | Small | Rare | $100 |
| Pearl Melon | Marine Cream | Large | Common | $75 |
| Diamond Lemon | Shiny Yellow | Medium | Very rare | $1,000 |
And its markup.
<table id="basic"> <tr> <td></td> <th>Color</th> <th>Size</th> <th>Rarity</th> <th>Price/100 grams</th> </tr> <tr> <th>Golden Grapes</th> <td>Golden Purple</td> <td>Small</td> <td>Rare</td> <td>$100</td> </tr> <tr> <th>Pearl Melon</th> <td>Marine Cream</td> <td>Large</td> <td>Common</td> <td>$75</td> </tr> <tr> <th>Diamond Lemon</th> <td>Shiny Yellow</td> <td>Medium</td> <td>Very rare</td> <td>$1,000</td> </tr> </table>
This creates a really basic, bare-minimum table. Notice the use of <TH> elements for cells that contain header information in this 2-dimensional table, where the first row and first column are headers. The empty cell at the top left corner is a <TD> element because it is not a header.
To make this table more readable we will color the header rows and columns and make the text in them bold, and also add more padding to lossen up the table. To make the table easily style-able we will use the <THEAD> and <TBODY> elements to wrap the appropriate cells.
<table id="colored"> <thead> <tr> <td></td> <th>Color</th> <th>Size</th> <th>Rarity</th> <th>Price/100 grams</th> </tr> </thead> <tbody> <tr> <th>Golden Grapes</th> <td>Golden Purple</td> <td>Small</td> <td>Rare</td> <td>$100</td> </tr> <tr> <th>Pearl Melon</th> <td>Marine Cream</td> <td>Large</td> <td>Common</td> <td>$75</td> </tr> <tr> <th>Diamond Lemon</th> <td>Shiny Yellow</td> <td>Medium</td> <td>Very rare</td> <td>$1,000</td> </tr> </tbody> </table>
table#colored { border: 1px solid #555; border-collapse: collapse; } #colored td, #colored th { border: 1px solid #555; padding: 8px 12px; } #colored th { font-weight: bold; } #colored thead th { background-color: #dcf1f5; color: #3c423c; } #colored tbody th { background-color: #f4fcf0; color: #354042; }
The result is something that looks better.
| Color | Size | Rarity | Price/100 grams | |
|---|---|---|---|---|
| Golden Grapes | Golden Purple | Small | Rare | $100 |
| Pearl Melon | Marine Cream | Large | Common | $75 |
| Diamond Lemon | Shiny Yellow | Medium | Very rare | $1,000 |
Center-align Cells of Short Data
Next we should center-aligned data which are short with only one to three words. We give this cells the CSS class name “center”. Although we should always try to name our CSS class names based on purpose and not appearance, e.g. “warning” vs “red”, there really isn’t any special purpose this class will serve except to center stuff so “center” is appropriate.
What about cells with numbers and figures? Should we center them. We will go to that later.
<table id="colored-centered"> <thead> <tr> <td></td> <th class="center">Color</th> <th class="center">Size</th> <th class="center">Rarity</th> <th>Price/100 grams</th> <tr> </thead> <tbody> <tr> <th>Golden Grapes</th> <td class="center">Golden Purple</td> <td class="center">Small</td> <td class="center">Rare</td> <td>$100</td> </tr>
#colored-centered .center { text-align: center; }
| Color | Size | Rarity | Price/100 grams | |
|---|---|---|---|---|
| Golden Grapes | Golden Purple | Small | Rare | $100 |
| Pearl Melon | Marine Cream | Large | Common | $75 |
| Diamond Lemon | Shiny Yellow | Medium | Very rare | $1,000 |
Cells with Numbers
Numbers are a little different from words because they have a distinct linear structure, do not use punctuation (except for commas and periods) and have consistent character widths. Take a look at the following image and you’ll see what I am talking about.

Try scanning the 3 different columns of numbers for a few seconds. Which one is more scannable? The difference might be minute but for someone working with large tables and long numbers, it can make a big difference.
As you can see, the center-aligned numbers are not as friendly to the eyes as the left aligned ones. By flushing numbers left, they line up with a straight edge and provide a clear starting point for the eyes. Center-aligned numbers have both sides jagged thus require more eye movement. To further increase the readability, monospaced fonts can be used for left-aligned numbers. Monospace characters all have the same width and thus provide a very consistent and predictable flow for the eyes. Eye movement should be less erratic when reading monospaced numbers.
Achieving this effect in CSS is easy.
| Color | Size | Rarity | Price/100 grams | |
|---|---|---|---|---|
| Golden Grapes | Golden Purple | Small | Rare | $100 |
| Pearl Melon | Marine Cream | Large | Common | $75 |
| Diamond Lemon | Shiny Yellow | Medium | Very rare | $1,000 |
#colored-centered-num .num { font-family: monaco,"Lucida Console",courier,mono-space,monospace; font-size: 13px; }
<tbody> <tr> <th>Golden Grapes</th> <td class="center">Golden Purple</td> <td class="center">Small</td> <td class="center">Rare</td> <td class="num">$100</td>
Alternating Row Colors
Reading rows in tables with a large number of columns is hard because the eyes are forced to stay within a line with little visual guidance, like walking in a straight line when you are drunk. People have always invented ingenious ways to facilitate horizontal scanning of table rows on paper, such as laying a ruler across a table, as a guide. Simulating a ruler on a webpage is probably overkill but we can provide similar functionality by using alternating table row colors. Alternating colors provide a simple and effective guide for the eyes to easily move across a table row horizontally because each row is visually distinguished from the one above and below it.
| Color | Size | Rarity | Price/100 grams | |
|---|---|---|---|---|
| Golden Grapes | Golden Purple | Small | Rare | $100 |
| Pearl Melon | Marine Cream | Large | Common | $75 |
| Diamond Lemon | Shiny Yellow | Medium | Very rare | $1,000 |
You can give a table row a different background color by applying CSS to a <TR> element.
<tbody> <tr class="alt"> <th>Golden Grapes</th> <td class="center">Golden Purple</td> <td class="center">Small</td> <td class="center">Rare</td> <td class="num">$100</td> </tr> <tr> <th>Pearl Melon</th> <td class="center">Marine Cream</td> <td class="center">Large</td> <td class="center">Common</td> <td class="num">$75</td> </tr>
#alternating .alt td { background-color: #edf7e9; } #alternating tbody .alt th { background-color: #e9f7e4; }
Nice Borders
The dark borders could use some refinements. Earlier we separated the tabl cells into <THEAD> and <TBODY> elements and this is perfect for detailed styling. We will also deal with the empty cell on the top left.
Let’s start by removing the top, right and left border for the <TABLE> element itself then add a 2px border to it to create a “shadow”, and then give the other cells nice borders. No need to add any more CSS selectors. We’ll just tweak the ones we already have. Firstly, the top header row.
#niceborder thead th { background-color: #dcf1f5; color: #3c423c; border-top-color: #e5f3f7; border-right-color: #c2e0f2; border-bottom-color: #c2e0f2; border-left-color: #e5f3f7; }
Next we style the left header column.
table#niceborder { border-collapse: collapse; border: 0; border-bottom: 2px solid #d2ecdd; } #niceborder tbody th { background-color: #f4fcf0; color: #354042; border-right-color: #d2ecdd; border-bottom-color: #d2ecdd; border-left-color: #eff7e9; }
Then the cells.
#niceborder td, #niceborder th { border: 1px solid #eee; padding: 8px 12px; }
Lastly we get rid of the empty cell. We can do this by applying “border: 0″ to the sole <TD> element which is the empty one in <THEAD>. But if you have other <TD>s that you don’t want to be empty, you will need to apply a class name to them so they are isolated.
#niceborder thead td { border: 0; }
And it’s done! The table has lost its harsh black borders, it now looks more aesthetically-pleasing.
| Color | Size | Rarity | Price/100 grams | |
|---|---|---|---|---|
| Golden Grapes | Golden Purple | Small | Rare | $100 |
| Pearl Melon | Marine Cream | Large | Common | $75 |
| Diamond Lemon | Shiny Yellow | Medium | Very rare | $1,000 |
Cells with Links
For links in table cells to be highly usable, they should have large click areas to make them easy to click and should have a different visual state when moused over. To give links a large click area, we need to transfer the padding of the surrounding table cell to the <A> (anchor) element.
#links tbody th { padding: 0; background-color: #f4fcf0; color: #354042; border-right-color: #d2ecdd; border-bottom-color: #d2ecdd; border-left-color: #eff7e9; } #links a { display: block; padding: 8px 12px; border: 0; color: #54b4c3; }
The result.
| Color | Size | Rarity | Price/100 grams | |
|---|---|---|---|---|
| Golden Grapes | Golden Purple | Small | Rare | $100 |
| Pearl Melon | Marine Cream | Large | Common | $75 |
| Diamond Lemon | Shiny Yellow | Medium | Very rare | $1,000 |
This concludes the end of the article. You can also view the full demo and source code (HTML and CSS). I hope you like it. Please feel free to correct me if I am wrong and also do share your tips in designing usable tables.
7 months ago
A good post, but you missed a big one: columns of numbers of the same unit (as the ones in your example) should be decimal-aligned. In this case that means RIGHT-aligned. This puts the ones in the same column, and numbers of a larger order of magnitude extend farther to the left than their smaller brothers. Try it; I think you’ll find that comparing numbers is much easier with such an arrangement.
Sure, there’s no easy way to decimal align figures with different numbers of digits after the decimal (well, in CSS3 there is, but that isn’t well-supported yet). In cases such as that you’ll need to pad or round your figures to have the same number of digits after the decimal.
7 months ago
I agree with Jon. Right aligning numbers is a must. You can also do the limiting of decimal places with a short bit of jQuery…
7 months ago
Great article.
A small nit-pick in the markup… would loved to have seen a summary attribute in the table element, and linking of “th” elements to “td” elements using “id” and “headers” attributes. :)
7 months ago
“Next we should center-aligned data which are short with only one to three words. We give this cells the CSS class name “center”. Although we should always try to name our CSS class names based on purpose and not appearance, e.g. “warning” vs “red”, there really isn’t any special purpose this class will serve except to center stuff so “center” is appropriate.”
Why not give them the class name “short”? Far more descriptive of the content being presented.
7 months ago
A think a better way of linking the TH to the TD, especially in this example where we have 2 headers per data cell is to use the scope attribute, e.g.
Color
Size
Rarity
Price/100 grams
Golden Grapes
Golden Purple
7 months ago
@ Jon and Jeremy
Really whether right-aligned number column is good or bad depends on how many digits are there after the decimal point and what are columns are beside it. Probably wouldn’t help if it’s between 2 left-aligned columns.
Padding the numbers so the decimal points align would be nice. Do you think a pure CSS solution is possible? I’m sure we can do it with JS and also <PRE> with extra spaces. But is that worth the trouble?
@ Russ and James
Well that would have added some complexity to my code so I pointed to a more complete table accessibility article in the beginning of this article.
@ Sam
Well there might be a later need to center longer stuff, who knows? But “short” is just fine I guess.
Hey guys thanks for the comments. Keep them coming. I’m learning a lot.
7 months ago
@ Aen
I have to agree on the right-alignment idea. Am I missing the point of using padding instead of right-align for the numbering? If the proximity to the nearby columns would be an issue, you could right align the cells and then add right side padding to move the numbers back over to the left a bit. Or am I simply not getting the idea here?
7 months ago
[...] Designing Tables for Usability | AEN UI What is more delightful than something that is usable? i wouldn’t appreciate anything, no matter how slick, that pisses me off by being a pain in the ass. Therefore being usable is being beautiful. (tags: aenui.com 2008 mes10 dia17 usability CSS table) [...]
7 months ago
[...] Designing Tables for Usability [...]
7 months ago
No need for an “empty” class; “thead td” will do that.
I also agree fully with people about the need to right-align the numerals. Ideally, you’d leave the $ to the left, but right-align the numbers to ensure easy comparison of numbers.
I also feel that the “tbody th” cells should be right-aligned, just as good form labels are right-aligned. It makes it clear that it relates to the information to its right.
7 months ago
Another vote for right-aligned numbers - it’s simply the standard and is what everyone who’s ever received a bank statement will naturally expect to see.
The currency symbol could go in the column header cell.
7 months ago
@ David
Basically that’s what I was trying to say. Padding in the sense of real physical padding, not in the CSS sense.
@ Kit
Thanks for pointing that out. I have edited the article to use your suggestion.
Right aligned numbers would make perfect sense if the number of digits after the decimal point is consistent. Rounding off is probably not so good information design when accuracy is critical.
I think tables are a little different from forms. For forms it’s more like reading than scanning. Right-aligned labels are good because it makes the label closer to its field. That provides a visual guidance when the eye moves from label to field. In tables, it’s closer to scanning and the eye move in different axis when comparing data. Right-aligning the leftmost column would have sacrificed the vertical readability.
@ Andy
I’ll check my passbook and credit card statement. I have never paid attention to that, probably because how well-designed it is. Good design is invisible.
7 months ago
[...] Designing Tables for Usability | AEN UI Design better tables. (tags: tables css xhtml design webdesign webdevelopment) [...]
7 months ago
same here. Numbers, especially currency, should be right-aligned. Usable? Ask anyone in accounting or finance, anything otherwise is design-fluff.
speaking of usable, what is the first field in the comment form for (no label?)
7 months ago
Here’s something to illustrate my point which is right-aligned numbers makes sense when you have consistent number formats. Add in commas, varying decimal places and units, right-aligned numbers become substantially more difficult.
Screenshot of stockquotes table taken from AOL Money & Finance. Numbers under “Most Actives” have a consistent number format and decimal places, right-aligned in this case is perfect. Numbers under “Biggest % Gainers” is a different story, with varying number formats that defeats right-alignment.
The edited screenshot now with left-aligned numbers under “Biggest % Gainers”. Still hard to read but definitely better than right-aligned.
So if you have control over the format of numbers, use something consistent and right-align them. If not, use left-alignment.
7 months ago
As a heavy user of financial tables, I’m glad to see so much discussion about making tables more usable.
Two things jumped out at me in the final example. One is right alignment, already mentioned.
The other is making it clearer that the row labels are links. Someone seeing the table for the first time wouldn’t know the labels are links unless they moused over them. Since most tables don’t have links, most people probably wouldn’t think to check for links.
Making the labels underlined by default rather than on mouseover would make the links more obvious. Alternatively, you could use an asterisk or footnote number that is underlined to show the link.
Great to see this level of detailed discussion about tables because it’s an area that can make a big difference to a lot of people.
7 months ago
[...] Designing tables for usability on AEN UI [...]
7 months ago
Actually, web browsers render numerals as monospaced in most standard fonts (Georgia is an exception). You don’t need to specify a monospace.
7 months ago
the first paragraph in my previous comment is a blockquote from the article. Your system stripped the tag, which made my comment meaningless. Oh well.
5 months ago
Really great article. Simple and to the point. Thanks.
5 months ago
What about using TD { text-align: “.” }
5 months ago
Jon Plummer’s right alignment comment was so good I had to demonstrate it:- http://www.flickr.com/photos/kaichanvong/3194118428/
Interesting post and I think if anything it’s good to share with people that tables should be used for displaying a table layout rather than full design layout. Which is what CSS layouts with positioning and floating is all about.
Ironically Flickr is totally built up in tables. Boom boom.
5 months ago
I wish I could edit :P
Also I think it’s important in some cases to think about Definition lists. One amazing f-e developer, Oleg Skrinda pointed out that this is something which can do great wonders for accessibility/usability.
I think maybe this post has mixed up usability with accessibility :P A screen reader doesn’t read data in the same way as a / etc… and that’s one of the key factors to using a table.
That way you can have the TH relating to the TD elements and explaining various parts of it. Say, “An Event apart” is on “12th June 2009″ at “Boston, USA”.
A blind user will find that difficult to understand in CSS layout - and so the table is a great combo for many different types of people.
http://www.maxdesign.com.au/presentation/definition/ <- great examples of Definition lists.
5 months ago
@ Tixiv. I just went to check out W3 and the text-align property does accept a string as a value. The spec must have been created for what we have been arguing in the comments! Unfortunately, even as a CSS2 spec, it is not supported in FF3.
@ Kai Chan Vong. The right-aligned numbers does look more readable. As for definition lists, they are more suited for key/value pairs, e.g. profile information. If you have read the last part of the second paragraph of this post, you’ll see that I have linked to another article on table accessibility.
Thinking about what you said about the blind user, “An Event Apart” and the date and venue. I wonder if the best thing would be to just present the information as a linear sentence.
5 months ago
[...] 4. Designing Tables for Usability [...]
5 months ago
Just found this interest website from ping.sg. I’m a web development student and I study HCI too. This website comes in handy for me. Check out my website too http://www.mybaby.com.my/
5 months ago
Hi Jessen, thanks for your comment. It is nice to have people who studies stuff like HCI reading my articles. It would be great if you can offer your insights and take part in the discussion of the topics.
Is mybaby.com.my something you’ve worked on or are you selling baby products?
3 months ago
I agree with Dominic. Make the links underlined and blue. It’s what people expect.
Also, I think the common practice is to remove the dollar signs from the numbers, and indicate dollars in the header, like this: Price/100 grams ($)
1 month ago
[...] Designing Tables for Usability | AEN UI [...]
4 weeks ago
Not able to download the source code. Can u please look into that.