Designing Tables for Reusability
uxdesign.cc – User Experience Design — Medium | Havana Nguyen
Written by Ada Rafalowicz and Havana Nguyen
“If I had an hour to solve a problem I’d spend 55 minutes thinking about the problem and 5 minutes thinking about solutions.”
It is so tempting to jump straight onto paper or Sketch or Axure and start building. In environments where shipping fast is a constant demand, it’s easy to leap headfirst. And while research and strategy sound like barriers to shipping fast, what if they actually helped move production faster?
We are Havana and Ada, an interaction designer and a visual designer from CareerBuilder. Our visual design lead, Mark Patterson, tasked us with designing a standard table UI pattern that could be used across multiple product lines with different use cases and different target users. Our approach involved getting quickly to the core of the purpose and problem early on, putting our ideas through bullshit tests early, and communicating constantly on the developments. We were able to generate an efficient design solution, get the team’s approval quickly, and validate through user testing.
Tables Are Hard
When we reviewed prototypes from across product teams, we saw that tables were inconsistent — they had a diverse array of competing UX decisions. The sizing, placement of links and CTAs, filtering, sorting, and pagination were all over the place:
Tables from our company’s other product lines
We needed a pattern that could universally serve all use cases across all products and serve future products and features.
Our Visual Design Lead delegated specific UI elements, and we admit that when we were assigned tables, we were pretty intimidated. It was a pattern that was used on almost every product and to complicate matters further, CareerBuilder’s products serve multiple types of users: job seekers, recruiters, and HR departments. Each product contain drastic differences in use cases, user goals, and functionality. How could we create something that could be flexible enough?
To top it off, we were both in different cities, so all collaboration had to be remote.
As soon as we were assigned tables, we set up a quick hour-long conference call. Our objective was to step back and uncover the big picture:
1. What is the user even trying to do on a table? On the conference call, we looked at several examples from pattrns.com and tried to extrapolate the objectives and purpose behind a table. We eventually concluded that there are 3 core user goals with tables:
a. To browse lots of info at once, e.g. show multiple items and their statuses
b. To determine and execute actions quickly, e.g. deleting multiple rows, downloading multiple items, etc.
c. To compare information, e.g. how many items are completed versus how many are in progress
2. What are the main design challenges on a table? We need to design the table to allow sorting, multi-selection, batch actions, and the ability to group data. Not every table will need every feature, but we needed to make sure we were addressing these features.
3. Can we break the table into smaller parts? We broke down the table into these components:
- expanded view,
- edit mode,
- treatment of actions,
- table customization,
- cell truncation,
- icon/imagery usage,
- and unread/new indicators.
We split these up between the 2 of us.
Throughout the 5-week process, we met 4 times to touch base and align our efforts and thought process. After that initial meeting, we worked on the components we had assigned ourselves and just shotgunned some initial ideas for each component. We collected these ideas and then set up a meeting 5 days afterwards with an open invite to the UX team. In this “early iterations” meeting, our goal was to simply get our initial solutions out in front of as many eyes as possible. Since there were so many use cases we were not familiar with, we wanted to run these ideas through a bullshit test, weeding out usability issues, functionality gaps, and point out potential issues with our ideas. Not only was the UX team there, we also invited the main developer to make sure that our ideas were technically feasible with the resources available. We set up this meeting to avoid wasting time on designing solutions that would run into major problems in the final iteration. It also ensured team buy-in early on.
Notes and sketches for tables
We captured that feedback, and then went back to work creating another round of iterations to accommodate the issues that were brought up. Throughout the process, we also had a mid-way meeting just to check on each other’s progress, identify what is “done” and what needs more work, and then a 4th meeting right before the presentation to the team to narrow down options to present, proofread, and then make sure we mocked up any states we missed.
In this process, we used Sketch and an internal company style library that we loaded using Craft.
Our process (Credit: Ada)
The Components of a Table
In case you are designing a table yourself, here is what we did with all the different components (and we used dummy data so that the UI stays content-agnostic):
Before, we had a simple pagination string with a display of the number of results. What happens if a search conjured hundreds of pages and you wanted to jump to page 563? It would be a pain to constantly go through 562 pages to get to it so we introduced a “Jump to page” dropdown. We also included a “Show X results” dropdown so the user could customize what they wanted to view. Our full pagination arsenal looked like this:
However, it then dawned on me that I wasn’t quite sure what the pagination string would look like if I was on page 4. Pagination ended up requiring some heavy IX work.
Pagination behavior as user goes through the pages
In the end, we allowed each product team to decide which parts of the pagination arsenal would work best for their product.
When you design something to be used across multiple products, you have to be flexible.
Different display options for pagination (Credit: Mark Patterson)
The main thing we learned from designing the pagination was this: dig into the step-by-step process of a pattern to find the hidden complexity — spoiler alert: there is always hidden complexity.
A useful feature found across our product verticals was the ability to edit a specific cell’s content. In one of our products, the current design was to have all the cells that were editable as text-input fields visible at all times. This made for an awkward user experience — how are users supposed to save the edited data in the field? That wasn’t clear in the current design.
Open text fields for editable content
Another issue with this approach was that it was too easy to make mistakes. You can imagine how easy it might be for a user to accidentally edit the wrong cell — can you undo? Cancel? Does it save automatically? The interaction was unclear.
What we did like about this pattern was that it was obvious what was editable and what was not. In the example above, the user is able to change the artist name and email address but not the date. We wanted to come up with a solution that retained this but set up more accurate expectations for the user.
At this point, the vast majority of users are familiar with certain iconography, in this instance the pencil, checkmark, and “x”. The pencil is used to indicate editable content across the web, we decided to implement this into our design.
Edit icons — gray by default
At first, we displayed the pencil in grey. When the user hovers over it, it turns into the hyperlink color. A colleague brought up a good usability point: what about mobile users? It’s impossible to change the color of the icon upon hover. Would they figure out that the greyed out pencil is clickable? We conducted a user testing session to find the answer to that question. The feedback we received from users was that in most instances, they completely overlooked the greyed out pencil. Our solution was to change the pencil into the hyperlink color, that way the user knows where to find it immediately.
Once a user clicks on the pencil, the text-input field appears alongside a green checkmark and a red “x”. From our testing sessions, our users easily figured out how to change the cell’s content once they had clicked on the pencil. Turns out keeping it simple works!
We were worried about placing the “Edit” action outside of the Action column, so we tested it. 7/10 users went straight to the pencil icon despite having been exposed to the actions dropdown first. Consistently, users suggested that the pencil should be blue by default as a few did not immediately notice it.
Quote from user: “The gray edit symbol is quite faint and quite difficult to see but when you do see it, it’s very simple and very synonymous with editing and changing things. I quite like that, it’s very nice.”
Final “edit mode” treatment
Treatment of Calls to Action
As mentioned above, the treatment of the CTAs varied the most across all the prototypes. Sometimes the CTAS sat at the top within the table, sometimes at the top as buttons, sometimes within the table cells as buttons, or icons, or sometimes within a dropdown — they were scattered everywhere.
Since one of the user goals of a table is to take actions quickly, we knew we couldn’t have our users scanning all over the table for that action. They had to be in one place. We also identified other questions: will the CTAs be text links at the end of the row? Top of the table? Do they need icons? What if there are more than 4 actions? How do we save the real estate for the rest of the columns? We set a rule to place all actions at the end:
Table with a single action per row: displayed as icon + labelTable with 2 actions per row: displayed as text linksTable with more than 2 actions per row: displayed in dropdown
We displayed up to two actions to allow the user to access them efficiently, but since three actions would take up quite some space on the table, we put them in a dropdown. For a few rounds of iterations, we debated whether or not to use icons with the labels but since we don’t know all the potential use cases in the future, we decided that including icons would possible force the designer to source an icon for some pretty difficult actions to depict, such as “[example.]”
As mentioned earlier, the only action that does not sit in the dropdown is “Edit.” “Edit” takes the form of a pencil icon and lives in the corresponding cell to allow inline editing. Placing it in the cell sets the user’s expectations that that is the content you can edit, rather than making them think the entire row is editable and then disappointing or frustrating them.
And of course, what about applying actions to multiple rows? It would be a huge pain in the ass to click the action column and then the action one by one for multiple rows. We borrowed a pattern from Gmail, where if even one row is selected, a “Batch Action” bar would appear at the top. The appearance of the bar in Gmail was a bit too subtle, so we used a more drastic color change to draw the user’s attention.
Since there could be several headers and columns of data, sometimes we are limited to what we can display based on the width of the table. In some cases, a table may allow the user to pick and choose what columns they want to see. To achieve this, we had to make the selection process clear and communicate capacity. We did this by disabling the selection once the user has selected the max number.
With limited space, there are bound to be problems with content length in some of these cells. Do we allow the text to wrap within the cell? Initially, we were inspired by this Dribbble shot by Virgil Pana:
It was a beautiful solution, so we met with the developer to consult on its technical feasibility.
We learned that even though it was possible, the table would involve very complicated math that may take a long time to build out. Would the effort be worth diverting attention away from other projects and deadlines right now? Plus, by how much would that complexity be multiplied if there was also the option to customize the table? Again, this is why it is so crucial to involve developers early! We decided that it was not a mission-critical feature and it was not worth the trouble for right now, so we came up with an alternative solution involving a tooltip with the full content:
Truncated table cell and tooltip
Usage of imagery and iconography:
While we were still hammering out the design details of our table, after already developing a certain fondness over the zebra stripes, a colleague brought up a use case we hadn’t considered. In one of the product verticals, a requirement was to upload logos into a table, and as many logos aren’t transparent, this would make the table look extremely awkward if it happened to land on a grey row. As this was a requirement and we couldn’t just tell them to forget about it, we had to come up with a solution. This was another use case where keeping it simple is for the best! For now, we decided that we would include instruction to recommend to our fulfillment team to upload transparent PNG logos. Luckily, the users uploading the logos are members of the client fulfillment team so our users would be more tech-savvy than our average customer.
After we thought we finally had the whole zebra striping thing down, another colleague brought up a use case where there are warning indicators within a cell. The entire cell’s background color was altered so that the user at first glance notices that that cell needs their attention. Although, aesthetically, this didn’t drastically change the table, it did present some development issues. What opacity should be allowed? Do we want developers to worry about layers of colors on a single cell or row? To keep it simple yet again, we decided that using icons should suffice but that if users struggled with this, we would then resort to the highlight.
Two treatments for “warnings” within tables (Credit: Rachael Dudziak)
Viewed vs. Unviewed Visual Indicators
We explored colored dots and vertical bars to mark unread items. The dot blended into the table completely. In order to make it more noticeable, we would have to also bold the text attached to that dot in that row. Then our colleagues brought up another point: what about checkboxes? Would the dot live next to the first cell with the checkbox, or the second cell with the text?
Early solution for “unread” items
The dot turned out into a bad solution both functionally and aesthetically so we opted to go with the vertical bar. The bar was simple and effective and demonstrated clearly that that row is unread. It is also a common pattern on other tables we researched.
Sometimes, there is too much data on an item that a table cannot hold. Expanding a row within a data table is now a common pattern found across a myriad of applications. In our research, we came across a pattern that groups expanded content well with its associated row:
Expanded View example from Patternfly
The specific row that is expanded is grey, differentiating it substantially from the rest of the rows. The related content is in its own rectangle surrounded by a border.
We were also inspired by another pattern where a “unifying bar” tied the row and the expanded part together, which makes it obvious to the user that this content is all related.
Expanded Table (Credit: Kosten Kos)
We decided to pursue both treatments with our table designs. We made the expanded row in question blue and added the unifying bar to the left.
1st and 2nd iterations of Expanded Row
The 1st iteration looked too much like the selected state. The dark blue bar seemed to work, but wait — we’re already using this vertical bar to signify unread rows. How do we now differentiate unread states versus expanded states in order to avoid confusing our users by presenting them with a merged blob of unifying bars?
3rd iteration of Expanded Row: thicker bar
At first I decided to increase the width of the bar as well as change its color. The increased width of the bar made it look awkward and the dark blue was still too close to the color of the “unread state” bar. We presented our solution to the team and they came up with an even better solution: make the bar the same width as the unread state but make it grey.
4th iteration of Expanded Row: grey bar
Padding and margins are vital to visual design and has to be specified to the developer to ensure aesthetic integrity. We created the guide below so that our team can create consistent tables no matter what project it’s on.
Padding and margin documentation (Credit: Ada)
Presenting the table and testing it out
The tables received very positive feedback from our internal team and we ended up surprising folks with how far we were able to get on this pattern. Of course there were a couple things that needed refinement, but many of the components got approved and were sent off to development and documentation!
But despite the positive reception from our team, we wanted to validate our assumptions: does this make as much sense to an outsider as it does to us? Would a user know to access the actions in the dropdown? Is the exception for the Edit action confusing? Was the pagination clear? We teamed up with our user researchers, Kiayni Spearman and Michael Pate, to do some basic usability tests via UserTesting.com. The researchers helped us devise a test that would prompt the user to do these 3 things:
1. Ask the user to perform some action on an item
2. Ask the user how many items are in the list and which page they’re on
3. Have the user edit someone’s email address
The 10 videos from UserTesting.com all came in within 2 hours of publishing it.
On finding the actions in the dropdown:
“Although there was no one-click button to delete the account I thought it was intuitive because the headers at the top of the table tell me very clearly where to click on to see a list of actions that I can do in relation to the entry. I pretty much knew how to proceed with deleting that entry even though I was looking at the table for the first time.”
“I [was] aware of the actions column [and assumed] that any other action would be located there.”
However, our test did show that the pagination was a bit confusing for the participants. But thanks to actual feedback from both our team and the participants, we had a clear direction on what needed more work instead of circling the drain, trying to figure it out and second-guessing ourselves.
Crafting the standards and master pattern for the table taught us a lot. On problem-solving, we learned:
- Meet early and write down a plan of attack — step back to ask WHY
2. Spend more time defining the problem than you do working on the solution
3. Get your bad ideas out fast; show people your ideas early and dissect pushback, critique, issues, etc. Involve several perspectives EARLY to avoid wasting time on solutions that won’t work
4. Break it down into small, more doable components and discuss often; delegate those components and then delegate the final deliverables
5. Keep ego out of it! Because we defined our goals and objectives early on, we were focused on that and let go of any emotional attachments to the solutions themselves, which made it easier to accept and implement feedback
By implementing the above, we were able to make smart decisions quickly and reach approval and validation fast, despite not being in the same office. Now, our team has two point of contacts to consult regarding tables and documentation and re-usable elements that can be flexible for any product moving forward.