Ultimate guide to table UI patterns

Many agree that tables are a phenomenon in user interface design: they are very important parts of user interfaces but often overlooked. Tables show structured data and their purpose is to make that data readable, scannable and easily comparable. The thing is that in many cases tabular data is obscured. This is why tables have bad reputation and many find them boring.

The truth is that the are everything but boring. For people who need tables in everyday work they are hated element that makes them scream. And it shouldn’t be this way. Here are some of the patterns that can help in creating less evil tables.

Alternating rows styling

Ok, this one is pretty obvious. But is it? Take a look at the web applications (and websites) today and you will see that many don’t apply it. So it is not obvious and that’s why it’s first in the list here.

By styling alternating rows differently you increase the ability of users to distinguish between overcrowded data in multiple rows and columns. You can use background color or background image. If background color is used it should be just slightly lighter/darker than a page background. For background images you should choose subtle gradients that match your color scheme. You can also combine background colors/images with table borders. Table header and footer should be easily recognizable and to achieve that you can use darker (or lighter) colors than table row colors.

BlinkCampaign uses subtle green color for alternate rows while keeping the header a bit darker.

Full row selection

If there is a single action that can be performed on a specific row, you can make the entire row clickable. This expands clickable area and declutters an interface. This can be used if, for instance, the only action you can perform on each row is view details. Each row should have hover state styled differently. There are several ways to achieve this effect, among which I would recommend you RowSelect jQuery plugin.

CrazyEgg uses full row selection to expand the details of the current selection (we’ll talk about this pattern a bit later). Row which is being hovered is slightly lighter. I really like how they designed this area (as well as the rest of the application).

Table sections

When you need to group related rows you can consider using table sections (or table grouping). A section is a part of the table that groups related data. All groups shares same set of columns. For example, in a table that shows list of countries, regions are natural way to group rows. Each section should be styled differently and can be collapsible/expandable. Under each section you can show summarized data, if needed.

PulseApp uses table sections to show income and expenses details, but also to group data in subsections that will show even more details. Each section and subsection is expandable.

Sorting

Sorting is used for cases when users have difficulties in finding a row they want in a very large set of data but they don’t know any keyword that can be searched by. Users also sort tables by columns when they want to compare adjacent information.

The common practice for enabling sorting on tables is to make header labels clickable. A column by which the table is sorted should be marked. This is usually done by placing an arrow next to column name, indicating in which order the column is sorted (ascending or descending). Clicking on a column that is already sorted should just reverse the order.

There has to be a clear difference between sortable columns and the others that aren’t. It is a good practice to sort table by default by one of the key columns.

Quite usable plugin is TableSorter which is very simple to use. It sorts many known data types and you can define your own as well. It also supports multi-column sorting, but I a not big fan of it anyway.

OneHub application clearly marks the sorted column and sorting order. What I like about this design is that it uses realism even in such small details.

Filtering

Filtering is very useful when you deal with large amount of data. Use dropdowns, radio buttons or checkboxes to make filter selection. In the example below, builditwith.me uses dropdowns to filter the list of people by profession, interest and availability.

However, you can perform filtering only by predefined set of values. For instance, you can filter a list of jobs by it’s type: full-time/freelance or by type: design/development. This means you can’t filter by First/Last name because there is infinite number of variations. In this case you can use live filter which uses keywords to filter data. For live filter you use input field where users can type any keyword and list is filtered by keywords found in any column.

Builditwith.me has several filter options above the list and live filtering below it.

Pagination

When dealing with large amount of data it is a good practice to split them in pages. Pagination is commonly used pattern but in many cases it is ineffective. This works for search engines but that doesn’t mean it will work in all cases.

Product Planner implements pagination in a common way – with page numbers and prev and next links. But can you tell what is on page 2? Page 3? Sure you can’t. But standard pagination can be improved. Take EveryBlock example shown below. Since it is a large addressbook, they used numbers and letters to define pages. Although in their case all pages are shown this would work well with hiding pages as well. You can use the similar approach for other criteria by which tables are sorted. If table is sorted by date, you can show date ranges instead of page numbers (Page 1 can be shown as Feb 10 – Feb 12, and so on).

If pagination links become too wide, you can use common page numbers (as seen in previous example) and show additional information while hovering over links.

Continiuos scrolling

As a contrast to pagination, continuous scrolling reveals new sets of data while you scroll down the list. There is no option to go to a specific set of data as it is the case with paging. Instead, new set of data is being added to a list. During the load time a progress indicator should be shown. In the example below, a progress indicator on dzone.com is showing how many items are loaded.

There are certain usability and accessibility issues with this pattern so you should test if this work with your users. You can read more about this pattern on UI Patterns.

There is a variation of this pattern (or actually another pattern) that doesn’t have such issues. Instead of revealing new set of data while scrolling, users can get the next set of data by clicking on more button, positioned at the end of the list. A good example of this can be seen on Twitter.

Fixed table header

This is a nice simple trick you can use to keep table header always visible. You can use it on fairly large and complex data sets to help users distinguish between many columns. I don’t have any live example so if you know one, please share! FixedHeaderTable plugin can be a good example.

Headerless table

If data in a table if self-explanatory there is no need for table header. A table that shows emails can be a good example – email subject, sender and date sent are self-explanatory and distinctive data which doesn’t require table header. However, there are cases when you won’t be able to remove table header. If there are ambiguous data, such as two dates, you would need a header description for these columns.

Rivalmap dashboard is a good example of headerless table. The information in the table is obvious and formatted in such way that no table header is needed.

Expandable rows

I already wrote about this pattern and created a small jQuery plugin that you can easily implement. The key point of this pattern is to enable adding additional information or functionality to tables. BuySellAds, for example, uses this pattern to show advertising details about each publisher, while keeping the most important information always visible in master rows.

Row actions

Tables are often much more than a plain placeholder for endless data. They also can be interactive elements that can perform specific actions. Actions are usually performed on a single row (they can be also performed on multiple rows, see next pattern). Actions can be shown inline, they can be revealed on hover or shown as a menu.

Inline actions

The simplest way to show actions is to place them in line with row data, at the beginning or the end of the row. In the example below, Mixx shows voting action at the end of each row which makes voting quite easy.

Hover actions

This is variation of the previous pattern that can be used in cases when you have multiple actions. By hiding them and revealing them on hover you declutter interface and make more space for data. Project Estimator by Astuteo shows edit and delete action on hovering each row.

Menu actions

If there are a lot of actions you can perform on each row, you can show them as a many that can be revealed on hover or click. DropBox utilizes this pattern very effectively. Since there are a lot of actions you can perform on each file, they show them as a context menu.

Actions on multiple rows

A good approach in many cases is to enable users to perform actions on multiple rows. Users can select rows by clicking on a checkbox, usually placed at the beginning of each row, and perform group action by pressing one of the available group action links or buttons. I will use DropBox in example also. Users can select multiple files and perform one of the group actions available from menu.

It is also a good practice to enable select all/deselect all functionality which instantly select or deselect all visible rows.

Final thoughts

The article covered the basics of the most common table patterns and some live examples. If I missed something please let me know! I also recommend you reading two more articles about tables: Big Table issue that tries to find an solution for tables that are so big they no longer fit in the viewport, and 15 Tips for Designing Terrific Tables that shows many different contexts in which tables can be used.

Thanks to Theresa Neil, one of the authors of Designing Web Interfaces, you can read about three more patterns that she documented: Inline Editing, Super Wide Tables and In-column Filtering.

60 Responses

  1. Adeel 26. February 2010 at 13:31

    Great article Janko (as usual)!

    I couldn’t agree more, I still remember the arguments I had with a client four years ago on why I cannot do a design which would have tables in tables with a background colour so we could achieve a border (instead of just adding border to one table!)

    I think table started off on a bad foot because everyone was trying layout websites using tables (rememer Yahoo! anyone?). But sad part is the insanity has totally reversed, now people avoid using tables at all. I remember seeing a really big open source bulletin board using <dl><dd> tags instead of <tr><td> "just because CSS should be used for layout".

  2. Kevin Babcock 26. February 2010 at 14:14

    Excellent article, Janko! Being a web developer ([i]not[/i] a designer) I often enjoy seeing great implementations of these ideas, which is what made this article so much fun to read.

    It is worthy to note that web frameworks like ASP.NET usually have third party vendors that provide many of these features in a single table (or "grid"). I personally prefer the Telerik components, as their RadGrid (http://is.gd/9ewzH) offers every single feature mentioned here and a few more as well. For others who don’t use ASP.NET, or who want to take a more client-centric approach, there are client-side grid implementations like the jQuery plugin jGrid (http://is.gd/9ewDu).

    Thanks again for the great article!

  3. Mona 26. February 2010 at 14:42

    Thanks for sharing your ideas, very useful and inspiring.

  4. Dmitry 26. February 2010 at 14:48

    One nice thing about the zebra stripe backgrounds is that they allow you to simplify the table design by removing horizontal borders as they’re no longer needed. This can help make your tables feel lighter and simpler.

  5. Nicolas Pascual 26. February 2010 at 16:47

    Wow Janko!
    Nice article, as ussual!

    As a newbie designer that kind of articles are so usefull to me. (Programmer trying to do nice pages).
    Please keep posting!

  6. Brian Cray 26. February 2010 at 17:10

    Nice work. I appreciate that you’ve taken 1 UI pattern – tables – and outlined common patterns for interacting with tables. It seems like, in the whirlwind bandwagon buzz of tableless web design, people forgot the real value of tables, which remain the best way to display tabular data.

  7. c. 26. February 2010 at 17:24

    @Adeel: I remember seeing a really big open source bulletin board using <dl><dd> tags instead of <tr><td> "just because CSS should be used for layout".

    It’s not that a table is used that’s the problem for a BB, but that it is misused. A table is being chosen 99% of the time for layout, rather than organization. Used properly, the author’s name, date submitted, what they said, etc. would all be in a separate column then the form elements’ display is changed via CSS. This is generally not done because IE doesn’t allow you to do things like tr, td { display: block } or rearrange them with absolute/relative positioning.

    I do agree that using dl in this situation is a misuse of the element. I have seen it misused for blog posts and comments as well in a well-received tutorial, and it’s likely that’s where they got the idea from.

  8. Iflexion 26. February 2010 at 17:30

    Good article. You know, with those contemporary forms and tables like continiuos scrolling and expandable rows sites are much more aesthetically pleasing. Flexible design and good usability features make sites nice looking and easy to use.

  9. Bobby Borszich 26. February 2010 at 17:37

    Great Post Janko,

    I am working very heavily right now with tabular data and the hover actions is something I will be implementing. I have found the jqGrid for jQuery to be a priceless tool. And for those that don’t feel as comfortable in JavaScript or jQuery they sell an ASP.NET pack that wraps it as a server control.

    Thanks again for taking the time to share your insights!

    Bobby

  10. Marco 26. February 2010 at 19:37

    What a great usability post – well done mate. Just off the record, did you draw the first image? If so, that’s freakin’ sweet! You should do that in all of your upcoming posts ;) .

  11. Joe Nuxoll 26. February 2010 at 19:48

    Another great way to handle auto-pagination of large data on a page was pioneered by the Apple Online Store. Essentially, to the user there *is* no pagination on the Apple Online Store. The basic idea is to use an empty div for each row (or cell in this case) so the initial page load actually is the correct height for *all* the cells to be visible – only the first "page" worth of rows is actually loaded with data. This makes an accurate scroll thumb to indicate true page height.

    As a viewer scrolls the data, use JS to detect scroll position on the page. As a viewer gets close to an unloaded "page" of data, load it asynchronously before the viewer arrives there. To the observer – all the rows were always there. To the server – pagination is happening as usual, based on the viewer’s scroll position on the page. You can be smart about loading pages – and only load that which is visible, and one above and below (much like a vertical-only version of google map tiles).

    You can see this in action here: http://store.apple.com/us/browse/home/shop_ipod/ipod_accessories/cases

    There is so much advanced web tech going on at the Apple Online Store – but of course nobody there is allowed to talk about it. Until you’ve long since left the company that is. :-)

    – Joe

  12. Janko 26. February 2010 at 19:56

    Thanks Marco! Yeah I made it, I upgraded my ArtRage to version 3 and played with it – it’s freaking awesome! They included watercolors now, and that is mean :) You can check out two new drawings I did with it http://www.flickr.com/photos/dzovan/

    Will surely use it for all articles from now on.

  13. Janko 26. February 2010 at 20:00

    Hey Brian, thanks for stopping by and commenting! I agree – the extent to which tables are misunderstood is unbelievable.

  14. Johann 26. February 2010 at 20:14

    Janko,

    one example of a website that uses fixed table headers is Google Adwords. Here’s an example screenshot: http://img132.imageshack.us/img132/6322/adwords.png

    I’m not so sure I like it because the UI still flickers to some extent. Let’s see how long it stays in AdWords.

    (I’m not a user of AdWords so forgive me if the keywords in the screenshot don’t make sense.)

  15. Saud Khan 26. February 2010 at 20:30

    I second you Brian. No doubt, table is one of the most useful UI pattern.

    Janko, thanks for writing another great article – Will be very helpful in reminding people the real value of tables (as Brian mentioned).

  16. Janko 26. February 2010 at 22:43

    Yes, tableless layouts contributed to tables’ bad reputation, unfortunately.

  17. Janko 26. February 2010 at 22:53

    I’m not a big fan of all-in-one grids, they’re usually hard for users (except for expert tech users).

  18. Janko 26. February 2010 at 22:53

    Good point, Dmitry, I missed that one!

  19. Janko 26. February 2010 at 22:54

    I am glad you find it useful :)

  20. Janko 26. February 2010 at 23:01

    Thanks for the comment Bobby! jqGrid is a really good and has some advanced features many other grids don’t have.

  21. Janko 26. February 2010 at 23:08

    Joe, thanks for sharing this. It’s a sort of continuous scrolling and it works well with that amount of data. It wouldn’t work well in Dzone’s case, though.

  22. Janko 26. February 2010 at 23:10

    Hey Johann, thanks for the example! I don’t use AdWords either ;)

  23. Chris Thurman 27. February 2010 at 17:21

    Besides a boost in usability, tables such as those mentioned in this article can have a large effect on the authority a site holds in the eyes of its users. A poor table layout can ruin the experience and lessen the credibility of a site while little details such as zebra stripes, sorting, etc. can boost the overall site perception.

    Great post!

  24. Jose 27. February 2010 at 18:03

    First, sorry for my bad English, I’m Spanish and my English is absolutly technician… Have you heard about DataTables? http://www.datatables.net/

    Ah, and a lot of thanks… very good article!

  25. Alex 28. February 2010 at 13:13

    You can find an example of fixed table header on deviantart.com friends page (you have to have an account to get to it).

  26. Alex 28. February 2010 at 13:29

    Some insight on pros and cons of different approaches would be appreciated in future posts. ;) Good job summing up basic aspects of tables design.

  27. Janko 28. February 2010 at 13:50

    I actually started with detailed explanation of each pattern but the article was too large, so I decided to go with overview and explore some of the patterns in separate articles. Thanks for the headerless example!

  28. JDS 28. February 2010 at 17:34

    avoid background in tables (specify color value instead). Otherwise causes probs for ppl with alternate browser color sets (i.e. high contrast black)

  29. Alex 28. February 2010 at 21:11

    Not headerless but ‘fixed header’ ;)

    http://img519.imageshack.us/img519/8068/bobhairstyles2.jpg

    The header sticks as you scroll the table.

  30. Janko 28. February 2010 at 21:38

    bah, my mistake, I thought fixed header. sorry.

  31. Shelly 1. March 2010 at 02:11

    Amazing! I wish I had the patience to figure out stuff like this. I struggle with word. LOL

  32. Bogdan 1. March 2010 at 09:16

    Sad pročitah ovo na SmashingMagazine, odličan članak, svaka čast!

  33. nik 1. March 2010 at 11:17

    I would like to see if there is some good use of Excell like tables on web. Tables which cells are at the same time data input also. I would like to see good execution of that kind.

    Great article. Thanks.

  34. Janko 1. March 2010 at 23:56

    Hvala :)

  35. Janko 1. March 2010 at 23:57

    Sounds like a job for jQuery&Ajax :)

  36. Matthew Lavigne 2. March 2010 at 01:31

    Great article! As much as I try and avoid tables as much as possible, this is a great guide when I’m forced to use them ;)

  37. Gaurav Mishra 2. March 2010 at 12:51

    I am highly impressed with the filtering approach these days ..first noticed that in tumblr

    Nice post!
    thanks

  38. Steffen Jørgensen 2. March 2010 at 16:07

    Great stuff Janko!
    Keep up the good work! :-)

  39. Philippe 2. March 2010 at 18:22

    Nice post.
    We uses those patterns every day but its good to put a name to it and see them grouped and well described.

    I can’t see where pagination is still useful continuous scrolling feels so much more natural.

    In building applications we always end up with tables as soon as we have a list with multiple variables.
    Headerless table make them less formal and work nicely if each content element is self obvious and we don’t need sorting then we can present it without column.

  40. Tom Something 2. March 2010 at 20:59

    I like zebra stripes for wide tables if the length of the data in individual rows can vary a lot. But I strictly use nth-child for this, stubbornly refusing to classify every other row just to accomplish this. If Internet Explorer doesn’t want to play, it can just sit there (still use thin rules as a backup).

    Interesting read. It’s always great to see people using tables in classy and appropriate ways.

  41. Elena 2. March 2010 at 21:15

    It’s really interesting article. Thanks for good information.

  42. Joost 2. March 2010 at 22:19

    Google Sitesis also using tables with a fixed header…

  43. Srini 3. March 2010 at 07:22

    I was truely amazed with the demos, esp for the Fixed Header & Column and the continuous scrolling. Thanks a ton for the nice article. :)

  44. TNk 4. March 2010 at 14:28

    Really great article! . Now and then i need to design large tables with content, this reviews of different examples open the possibilities :)

  45. Enrico 6. March 2010 at 00:08

    It is true.
    I anyway recommend jQuery flexigrid that is similar to jqGrid…with less features….
    but really quick and well designed.

  46. Theresa Neil 8. March 2010 at 06:41

    Excellent article!

    I couldn’t resist documenting a few more scenarios :
    1. Inline Editing
    2. Super Wide Tables
    3. In-column Filtering

    http://designingwebinterfaces.com/ultimate-guide-to-table-ui-patterns

  47. Janko 8. March 2010 at 15:06

    Theresa, thanks for the comment and thank you for thorough explanation on those three patterns! I added a link to your article at the end of the post.

  48. web design maidstone 8. March 2010 at 17:06

    Some good insights into UI, always helpful!

  49. Paginas web 8. April 2010 at 18:37

    Thanks for the resources!

    Muchas gracias por los recursos!

  50. Laura 14. April 2010 at 12:17

    I love tables!!! …when they are used in the right way! ;-)

  51. daniel 14. April 2010 at 19:43

    what about row selection and single cell selection behavior. how about combining these in a single table?

  52. ux23 19. April 2010 at 12:17

    Hi there,

    great article!

    Situation: You are on Page 2 and you click on a column label.

    What is the best behavior for a table with pagination and sorting support?

    #1 Sorting over the entire table (dataset) and you will stay on the same page (2).
    http://demos.telerik.com/aspnet-ajax/grid/examples/clientbinding/defaultcs.aspx

    #2 Sorting over the entire table (dataset) but you will be kicked on page 1.
    Inbox of hotmail http://www.hotmail.com

    #3 Only the data of the current page will be sorted.

    Thanks for answers!

    Take care

  53. Keith Davis 3. May 2010 at 09:10

    Hi Janko
    I’ve nothing against tables, guess they got a bad press when CSS and divs became the way to layout web pages.
    I agree with you that they are still brilliant when used for displaying data.
    Your examples show what can be done with a little, or even a lot of imagination.

    BTW – love the hand drawn graphic at the top (man pushing table up hill) – did you produce it?

  54. Nicolas 12. May 2010 at 10:19

    I like the second pagination example, but there can be a seo problem if too many links are found by search bots on a webpage (max 100 is recommended by Google for example) .

  55. Net Age | Web Design 15. May 2010 at 21:25

    Tables, oi….my love hate relationship with spreadsheets naturally extends to tables as well. Sugar coating pills make them easier to swallow, and the virtual sugarcoatings you so eloquently displayed here does go a long way towards easing my child-like reservations concerning tables ;-)

    Displaying comparative data and information works best using tables, and the subtle tricks you shared here helps the eye follow the right lines, and greatly reduces the risk of making mistakes due to eyes getting confused because of too much information. Lightly shading alternating rows or columns is a great design trick. Presenting information in a palatable way is one of the great challenges facing designers, and this guide helps a lot.

    Thank you sharing, Janko. Enjoy your weekend.

  56. Brian R Cline 30. May 2010 at 14:47

    Thanks, I found some of these tips extremely useful and will incorporate them into future designs.

  57. snipe 22. June 2010 at 04:49

    Great post, as usual. One quick comment though:

    [quote]By hiding them and revealing them on hover you declutter interface and make more space for data.[/quote]

    Actually not a huge fan of this one, from a UI perspective. If the user is looking for edit/delete functionality (and one would presume this is significant functionality), I don’t agree with hiding it. Once the user had gotten used to that UI, sure, they’ll know where to look, but if they’re new to the app, especially an app with a full UI and loads of functionality (or one that isn’t used daily, giving time for people to forget), I feel this can be frustrating.

    I like the look of it, and use many apps that offer that as part of their UI, but if an app is complex and I don’t use it often, it can be aggravating to hunt down. Just MHO, though.

    PS – "Website" is spelled wrong in your comment form :)

  58. Bobby Jack 22. June 2010 at 13:11

    Have you seen this ALA article about zebra striping?

    http://www.alistapart.com/articles/zebrastripingdoesithelp/

    While it’s quite a weak conclusion, it does suggest that zebra-striping isn’t necessarily of great value. It may well be an aesthetic thing (granted, zebra striping often [i]looks[/i] nice) as opposed to actually easing reading.

  59. Janko 22. June 2010 at 13:18

    I agree, that is a good point. I think it depends on who your users are. In case of web applications that are used a few hours daily and where you mostly design for intermediaries, I think this is acceptable. In other cases this need to be considered carefully.

  60. Janko 22. June 2010 at 13:26

    Yeah that’s an interesting analysis, thanks for sharing!

    I can’t say that I agree or disagree. When we did usability testing on some large financial reports, my team and I discovered that zebra striping actually helped users handle such extensive reports.

    But if ALA article is right and if stripping doesn’t makes it better/worse, the only thing we should consider is visual design.