Ultimate guide to table UI patterns

February 26, 2010

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 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 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.


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.

* * *

Remember RSS? You can subscribe to my blog here.


  • Adeel (February 26, 2010)

    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".

  • Kevin Babcock (February 26, 2010)

    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!

  • Mona (February 26, 2010)

    Thanks for sharing your ideas, very useful and inspiring.

  • Dmitry (February 26, 2010)

    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.

  • Nicolas Pascual (February 26, 2010)

    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!

  • Brian Cray (February 26, 2010)

    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.

  • c. (February 26, 2010)

    @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.

  • Iflexion (February 26, 2010)

    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.

  • Bobby Borszich (February 26, 2010)

    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!


  • Marco (February 26, 2010)

    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 ;) .

  • Joe Nuxoll (February 26, 2010)

    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

  • Janko (February 26, 2010)

    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.

  • Janko (February 26, 2010)

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

  • Johann (February 26, 2010)


    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.)

  • Saud Khan (February 26, 2010)

    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).

  • Janko (February 26, 2010)

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

  • Janko (February 26, 2010)

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

  • Janko (February 26, 2010)

    Good point, Dmitry, I missed that one!

  • Janko (February 26, 2010)

    I am glad you find it useful :)

  • Janko (February 26, 2010)

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

  • Janko (February 26, 2010)

    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.

  • Janko (February 26, 2010)

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

  • Chris Thurman (February 27, 2010)

    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!

  • Jose (February 27, 2010)

    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!

  • Alex (February 28, 2010)

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

  • Alex (February 28, 2010)

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

  • Janko (February 28, 2010)

    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!

  • JDS (February 28, 2010)

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

  • Alex (February 28, 2010)

    Not headerless but ‘fixed header’ ;)


    The header sticks as you scroll the table.

  • Janko (February 28, 2010)

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

  • Shelly (March 1, 2010)

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

  • Bogdan (March 1, 2010)

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

  • nik (March 1, 2010)

    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.

  • Janko (March 1, 2010)

    Hvala :)

  • Janko (March 1, 2010)

    Sounds like a job for jQuery&Ajax :)

  • Matthew Lavigne (March 2, 2010)

    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 ;)

  • Gaurav Mishra (March 2, 2010)

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

    Nice post!

  • Steffen Jørgensen (March 2, 2010)

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

  • Philippe (March 2, 2010)

    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.

  • Tom Something (March 2, 2010)

    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.

  • Elena (March 2, 2010)

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

  • Joost (March 2, 2010)

    Google Sitesis also using tables with a fixed header…

  • Srini (March 3, 2010)

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

  • TNk (March 4, 2010)

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

  • Enrico (March 6, 2010)

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

  • Theresa Neil (March 8, 2010)

    Excellent article!

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


  • Janko (March 8, 2010)

    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.

  • web design maidstone (March 8, 2010)

    Some good insights into UI, always helpful!

  • Paginas web (April 8, 2010)

    Thanks for the resources!

    Muchas gracias por los recursos!

  • Laura (April 14, 2010)

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

  • daniel (April 14, 2010)

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

  • ux23 (April 19, 2010)

    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).

    #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

  • Keith Davis (May 3, 2010)

    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?

  • Nicolas (May 12, 2010)

    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) .

  • Net Age | Web Design (May 15, 2010)

    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.

  • Brian R Cline (May 30, 2010)

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

  • snipe (June 22, 2010)

    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 :)

  • Bobby Jack (June 22, 2010)

    Have you seen this ALA article about zebra striping?


    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.

  • Janko (June 22, 2010)

    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.

  • Janko (June 22, 2010)

    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.