Tabular Data

How to display and allow manipulation of complex data at scale.

Octopus relies heavily on tables to display such core product entities as Projects, Tenants, Deployment Targets, Workers, Releases, Variables, and many more. It’s vital to our users that the information presented is easy to digest and act on. Otherwise, setting up and managing their deployments becomes unnecessarily complex.


Tables allow displaying potentially complex data in a structured, easy-to-digest way. They can also scale to large quantities of data (however, we have to consider performance optimizations in those cases to avoid negative impacts on UX).

When to use tables

How we apply tables will vary depending on context, but here are common user goals that tables are best suited for:

  • Finding item(s) that meet criteria: Well-structured tables with filtering, ordering, and search enable users to locate what they are looking for quickly.
  • Comparing data: tables make it easy to find outliers, analyze trends, and explore relationships between items.
  • Taking actions on items: tables simplify management tasks by allowing single and bulk actions on presented items.

Beyond these use cases, tables are ideal for displaying large quantities of data in a structured way, especially in scenarios when each item has more than three characteristics or relationships to other items that need to be portrayed.

Tables vs other ways of presenting data

Tables aren’t the only way to represent data—it’s essential to know when tables are most useful, and when a different mode of data display might be more suitable.

Component

Table

List

Card

Scalability

Unlimited items

Unlimited items

Less than 7 items

Scannability

✅ Yes

❌ No

✅ Yes

Searching

✅ Yes

✅ Yes

❌ No

Single and bulk actions

✅ Yes

❌ No

❌ No

Filtering

✅ Yes

❌ No

❌ No

Controlling display density

✅ Yes

✅ Yes

✅ Yes

Controlling data displayed

✅ Yes

❌ No

❌ No

Tables vs Lists

Lists don’t support data comparison and manipulation. While it’s possible to display many entries using a list, users will evaluate each entry individually because of the visual representation. When thinking about scalability, reconsider list usage.
Lists are helpful when you want to display an entity with fewer than three additional item characteristics (or associated actions). For example, a list of Spaces with only Space names listed or a list of users with only names and emails listed.

Tables vs Cards

Cards don’t support data comparison and manipulation either. Scalability is also an issue as reading through cards requires a lot of spatial reorientation, increasing cognitive load. Cards work best when displayed in minimal numbers.


Cards are useful in a data visualization context when leveraged to summarize data in dashboards or above tables. They focus users on key takeaways without the need to analyze all of the available data.

Considerations for table design

Content alignment

Tables: Content Alingment

Always match the table header content alignment to the body alignment. Content alignment differs depending on the contents of the cell:

  • Text: left-aligned.
  • Numerical: right-aligned.
  • Actions: right-aligned.

Content ordering and importance

Tables: Content Importance

Arrange the columns in order of importance from left to right. Consider bolder visual treatment for the left-most, identifying column.

Row styling

Appropriate row styling makes the data more readable, as it’s easy to distinguish between entries. Depending on the amount of data and interactions available within the table, consider:

Preview

Styling Type

Use Case

Row Styling: Horizontal Lines

Horizontal lines

Displaying complex data, often in various formats, with intention to reduce noise.

Row Styling: Grid Lines

Grid lines

Displaying complex, dense data, with intention to clearly separate all cells.

Row Styling: Zebra

Zebra stripes

Displaying complex, dense data, when rows are read only and don’t have additional states and interactions that could be easily confused with zebra styling.

Sorting

Tables: Sorting

Allow sorting columns, so users can easily customize the displayed data. Sorting should be toggled by clicking on a relevant column header (or, at minimum, the sorting icon and the accompanying text label) Use the most relevant type of sorting to the presented data. Most common sorting options include:

  • Alphabetical (A - Z, Z - A).
  • Size (Largest to smallest, smallest to largest).
  • Recency (Newest to oldest, oldest to newest).

Searching

Tables: Searching

Search functionality makes it easy to find targeted information within large datasets. The search field should be visually connected to the table and placed above it.


When using search in conjunction with filtering, keep the scope of the search to the columns that can’t be filtered. This approach might limit search to a single column, in which case, label the search placeholder with Search {objectName}.

Filtering

Tables: Filtering

Filtering is an excellent addition to searching. It allows users to easily find information, compare it across multiple dimensions, and narrow down substantial data sets.


When using filters in tables, display a summary of selected filters that’s easily accessible and clearly visually connected to the filtered table. Always provide a way to clear the selected filters quickly.

Responsiveness

Tables should be responsive and adapt to fit the available viewport. When there’s too much data represented in a table to display it within a smaller viewport without compromising legibility, use the following approaches:

  • Scrolling: add horizontal or vertical scrolls.
  • Column customization: allow users to toggle columns on and off to control display.
  • Column resizing: allow users to change column width to make content more readable.

Scrolling behavior

Table: Scrolling

Make sure tables are scalable. Information should remain easily understandable when users scroll vertically (many rows) and horizontally (many columns) across tables that won’t fit their viewport. When users start to scroll:

  • Vertically: freeze the header, so the data is always presented in context.
  • Horizontally: freeze the leftmost column containing identifying information about the viewed items to maintain context.

Another way of controlling horizontal scrolling is column customization.

Column customization

When a table has more than 5 columns, allow users to choose which ones they want to display. That way, they can focus on the most important information for their task. It also potentially removes the need for horizontal scrolling.

Display density

Display density refers to how tall the table rows are. Allowing users to control display density helps them view data in a way that’s most comfortable for them. It also allows them to switch between modes depending on context: a condensed view to see more data at once when using a smaller screen size or a more spacious view when using a bigger screen with less data.

Preview

Density

Row Height

Density: Condensed

Condensed

40px

Density: Regular

Regular

48px

Density: Relaxed

Relaxed

56px

Table actions

Use progressive disclosure when approaching single and bulk item actions within tables. Displaying buttons by default will clutter already data-rich tables more. Instead, display actions on hover on the row:

  • Single item action: display buttons at the end of the row and right-align them.
  • Bulk items action: display checkboxes at the beginning of the row and left-align them. Additionally, display the selected item count and choice of actions above the table.

Showing row details

It’s possible that you might need to make more data easily available in table context than would be comfortable to display by default. In those cases, consider the amount of extra information and whether users should be able to manipulate it:

Approach

Amount of information

Action support

Row expansion

Small

❌ No

Dialog

Medium

✅ Yes

Drawer

Medium

✅ Yes

Navigate to item page

Large

✅ Yes

Refer to Dialogs, Drawers & Wizards pattern for guidance in using these components.

Optimizing performance

Data-heavy tables can inevitably introduce visible performance issues when data takes too long to load. To decrease negative user experience:

  • Use pagination to display data in batches.
  • Optimize API calls to serve data quicker.

Accessibility

Using tables for layout

Tables shouldn’t be used to construct page layouts. Their sole purpose is data presentation.

Semantic markup

Use semantic markup to highlight specific table elements (such as th, td) in conjunction with appropriate ARIA roles. Describe the contents of the table using <caption>, and identify column headers by using scope= "row" and scope= "column".

Sequential and logical order

Organize data in sequential and logical order so it is easily understood. Content embedded within a table should be readable even without any design treatment or styling.

View flexibility

Cater to various needs by offering multiple ways of consuming and interacting with tabular data. Tables should be responsive, customizable, and viewable on smaller and larger resolutions.

Content nesting

Be careful when creating complex, nested structures within table cells. Inappropriate nesting will cause screen readers to lose track of the reading order, creating a confusing user experience. Navigating incorrectly nested tables while using assistive technologies will also be difficult.

Empty cells

Don’t leave cells empty. Where there is no data, use zero, nil, or N/A. If the represented data is numerical, use the numerical zero (0).