Designing Tables for Usability
17 Nov 2008
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.
Jon Plummer 17 Nov 2008, 11:33 AM
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.
Jeremy Skelly 17 Nov 2008, 11:53 AM
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…
Russ Weakley 17 Nov 2008, 6:11 PM
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. :)
Sam Hastings 17 Nov 2008, 9:21 PM
“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.
James King 17 Nov 2008, 10:41 PM
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
Aen 18 Nov 2008, 1:21 AM
@ 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.
David Millar 18 Nov 2008, 3:35 AM
@ 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?
rascunho » Blog Archive » links for 2008-11-17 18 Nov 2008, 4:04 AM
[...] 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) [...]
Max Design - standards based web design, development and training » Some links for light reading (18/11/08) 18 Nov 2008, 5:30 AM
[...] Designing Tables for Usability [...]
Kit Grose 18 Nov 2008, 7:00 AM
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.
Andy Towler 18 Nov 2008, 12:55 PM
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.
Aen 18 Nov 2008, 9:51 PM
@ 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.
links for 2008-11-18 | Yostivanich.com 18 Nov 2008, 11:12 PM
[...] Designing Tables for Usability | AEN UI Design better tables. (tags: tables css xhtml design webdesign webdevelopment) [...]
Eric 19 Nov 2008, 12:03 PM
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?)
Aen 19 Nov 2008, 12:58 PM
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.
Dominic Jones 22 Nov 2008, 4:29 AM
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.
Design finds at mariuszciesla.com | Mariusz Cieśla 01 Dec 2008, 1:17 AM
[...] Designing tables for usability on AEN UI [...]
michelangelo 02 Dec 2008, 1:01 AM
Actually, web browsers render numerals as monospaced in most standard fonts (Georgia is an exception). You don’t need to specify a monospace.
michelangelo 02 Dec 2008, 1:02 AM
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.