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.











General form design and usability guidelines also apply to search. Always provide descriptive labels so your search form looks obviously like one. One popular approach employed by many websites is to pre-populate the search text field with a phrases like “Enter Search Terms”, “Search here” and “Type and Search” and clearing the text field on mouse focus with JavaScript. This results in a more compact form design but suffers in accessibility because of the lack of a <label> tag. A
Let’s say you are a PC and Windows user who has heard good things about how Macs are less prone to virus attacks, more stable and generally a joy to work with, but you have also heard how people like you who grew up on Windows, find it hard to switch to a Mac. So you visit the Apple apple website to find out more for yourself. You decide to search for information on “switching”. Theoretically, the returned search results should include information on how someone can switch from PCs to Macs and also content from technical support information that involves powering on or off a Mac. In this case, only Mac 101 and Switch 101 are shown in the live search results, because they are more popular content. Thumbnails in each search result entry also provide hints of the content ahead, which is especially helpful when searching for let’s say… movie trailers.