Skip to main content
Odyssey Design System


Tables provide structure for displaying sets of data across rows and columns. They support multiple content types and some internal actions.

# Anatomy

# Behavior

# Sorting tables

Sorting Table columns is a common interaction for users. Following standard conventions will ensure a consistent experience:

Any sortable column should display the appropriate icon for its state: ascending, descending, or unsorted.

When an unsorted heading is clicked, the column should sort in ascending (A to Z) order.

When an ascending heading is clicked, it should swap to descending (Z to A) order.

Finally, when a descending heading is clicked, it should swap to unsorted.

When any column becomes sorted, the previously active column should return to an unsorted state.

Big and small planets
Information about the largest and smallest planets.
Jupiter 69,911 Gas giant
Earth 6,371 Terrestrial
Mercury 1,737 Terrestrial

# States

# Empty tables

If no data is returned - whether due to filtering or an empty data set - be sure to provide a null state for your users. If you can detect why no data was returned, make that clear in the tfoot. The data-null attribute will ensure the table styling is adjusted.

Big and small planets
Information about the largest and smallest planets.
Planet Radius (km) Type
Aw beans. This set of filters didn't return any results.

# Usage

Note that tables should not have a fixed width, nor should their columns. Browsers divide space based on content and forced white-space will hurt readability. To ensure rogue strings don't cause visual wonk, we limit cells widths to ~45 characters.

# Row headings

If your data set has keys on two axes, we also support setting the left-most column as a row heading. This is helpful when you expect the user tuseze a known value for data lookup (e.g. "Which missions went to Mars?").

Be sure to identify your row heading column as well. That is, don't leave a blank cell in the upper left. Our secondary headings need context too!

Big and small planets
Information about the largest and smallest planets.
Planet Radius (km) Type Descriptor
Jupiter 69,911 Gas giant Jovian
Earth 6,371 Terrestrial Terran
Mercury 1,737 Terrestrial Mercurial

# Row groupings

If you need to group rows by a shared data point, we also support using rowspan to do so. Otherwise, follow the same implementation guidelines as above.

Note: spanning multiple rows or columns may cause issues for assistive technologies.

Big and small planets
Information about some of the largest and smallest planets.
Type Planet Radius (km) Descriptor
Gas giants Jupiter 69,991 Jovian
Saturn 58,232 Saturnian
Terrestrial Earth 6,371 Terran
Venus 6,052 Venusian
Mars 3,389 Martian

# Content guidelines

Titles & captions should describe the table the user is viewing. They are not abstractions.

Reserve the left-hand column for your most important data. Cascade lower priority data to the right.

Don't use long column headings. Try to keep them as short as or shorter than your column content.

Don’t create complex interactions that change the state of the row. Tables are primarily for reviewing data, not interacting with it.

# Supported content types

The basic Table cell styling is based on what is most legible and scannable for a normal string of text. However, different data types may need alternate styling.

Currently, we provide extra support for numerical data, dates, Buttons, Statuses, and Checkboxes.

Big and small planets
Information about the largest and smallest planets.
Planet Radius (km) Type Gravity (g) Perihelion date Base status Travel
Jupiter 69,911 Gas giant 27.94 January 21, 2023
Base status
Storm approaching
Earth 6,371 Terrestrial 1.00 January 2, 2021
Base status
Mercury 1,737 Terrestrial 0.37
Base status
  1. Checkboxes

    Include checkboxes in the first column. The heading checkbox should check/uncheck all rows when clicked.

    If mixed, the heading checkbox should be set to Indeterminate.

  2. Numerical data

    We use tabular numbers and right-align figures for quick scanning.

    Leave off any units. Instead, specify them in the column's header.

  3. Statuses

    No extra styling is required when adding Statuses to your table. Ensure their labels are hidden and their column has an appropriate heading.

  4. Dates

    To maintain ease of reading, dates should not be line-broken. White-space is preserved throughout the column. This applies to all date formats.

  5. Empty cells

    If a cell is empty, use an en dash (–) to indicate this.

  6. Buttons

    No extra styling is required when adding Buttons to a table. They will resize to the "Small" variant and align to the baseline of other type in the row.

# Accessibility

# Titles and captions

Each Table should have both a title and a caption.

The title is the visible heading for your table. A concise, descriptive title will provide users with a direct context for your data. The needed context may be missing if you rely on page headings or surrounding body copy.

Captions are visually hidden. Providing a caption will give users of assistive technologies context for the table before it is accessed.

# Complicated tables

Try to refrain from using complicated table layouts that rely on colspan or rowspan.

This same advice applies to nested tables or hidden rows as well. They can introduce problems that make your table inaccessible for some users.