Data table



Data table organizes and displays information so it’s easy for users to scan, sort, analyze, compare, and take action.


Use a data table to organize and display data or a set of resources. Data table rows and columns provide built-in resizing, visibility, sorting, pagination, reordering, and filtering functionality.


Table anatomy
  1. Title: Describes the purpose of the data table.
  2. Description (optional): Describes the data in more detail.
  3. Filter: Customizable options to filter the data table’s data.
  4. Search: Field to search the data table’s content.
  5. Data table settings: Allows users to customize the table density.
  6. Column visibility: Allows users to show or hide columns.
  7. Column header: Customizable label that explains the type of data in each column. The header may include optional sorting behavior.
  8. Column: Displays one type of data.
  9. Row: Displays applicable data values for one item. It can be selected or expanded.
  10. Reordering: Uses drop-and-drag controls or numbers to reorder data.
  11. Pagination (optional): Allows a data table to be navigated on multiple pages when it contains more rows than can be displayed on a single page.


Storybook failed to load. Please connect to the VPN to access.

Open the component in Figma.

When to use

Use a data table for these scenarios:

  • When users need to filter and sort, analyze, and compare data.
  • When users need to navigate to a specific piece of data to complete a task or display a set of resources.

When not to use

If the goal isn’t to compare information but to include content of the same type, you can use a simpler component.

Use a resource list instead:

When you need to group related content, whether text, images, or data in a continuous vertical index. This allows users to scan items in the list and take action (navigating, selecting).


A data table offers the following cell types to support our data content types. Alignment is automatically determined by the data content type.


A basic cell with text.


A basic cell with tabular numbers.

See link.


See status.


Individual actions can be triggered by buttons and checkboxes. Multiple actions can be included in the action menu.


  • Include checkboxes in the first column only.
  • A heading checkbox should allow all rows to be selected/unselected.


  • When including a button in a cell, no extra styling is required.
  • Use the small button variant.
  • The recommended maximum is two buttons. Otherwise, use an overflow menu to contain actions.

Overflow menu

  • Can show the overflow menu alone or can be implemented with buttons.



Action placement

Buttons are placed at the top right, with the primary action always furthest to the right.




Empty state

If a data table doesn’t have access to the data that should populate it, an empty state will be displayed. See Writing for empty states.

Interactions > Empty State


All data table rows, interactive or not, have a hover state for easy scanning.

Behaviors > Hover State

Selected state

All data rows except the headers can be selected. Users can perform a single action or batch actions against selected items.

Behaviors > Selected


Data isn’t editable by cell or column, so an error only occurs if the entire data table can’t be rendered.


Skeleton loading

The skeleton loading state indicates the data isn’t loaded yet. The skeleton state should show five rows maximum.

Interactions > Skeleton


When the content of a data table is wider than the maximum width of the viewport, the content area will scroll horizontally.


Table density

  • Allows users to set the data table vertical padding density as Default, Expanded, or Condensed.
Interactions > Table Density

Column visibility

  • Allows users to select columns to show or hide.
  • At least one column must remain visible.
Interactions > Column Visibility

Resize columns

  • Designers can enable columns to be resized.
  • Uses then see, and can use, a column resize grip to adjust column width.
Interactions > Resize Columns

Sort columns

Columns can be sorted in ascending or descending order by clicking on the column header.

  • Only one column can be sorted at a time.
  • Sorted columns have three states represented by an icon (unsorted, ascending, descending).
Interactions > Reorder Columns

Expand rows

  • Expand a table row vertically to show or hide additional content.
Interactions > Expand Rows

Set number of rows

  • Designers can control the number of rows visible in a data table.
  • Users can also choose the number of rows to view as one page.
Interactions > Set number of rows


  • Filtering is triggered by a form of the menu button. See menu button
  • Designers can add or create the filters appropriate for the data.
  • The filters can be presented as Selects, Checkboxes, Radios, or Inputs depending on the filter options and desired outcomes.
  • Users then select filters from the menu. These filters are then shown in tags at the top of the data table.
Interactions > Filtering


Use when your data table includes a large number of rows to keep page length and load time reasonable.

Pagination variants

Known number of pages

  • If technically possible, the number of pages of data will be calculated and shown, taking into account the number of visible rows set by the designer.
  • Users can navigate by page number or can also choose either the arrow-left and arrow-right icon buttons to navigate to the Next or Previous page.
  • This functionality is still in development. If you need to include the number of pages, work with your Eng partners to confirm it’s possible and that they can code it.
Pagination > Regular Pagination

Unknown number of pages

  • Many Okta UIs have technical constraints that make calculating and displaying the total number of pages impossible.
  • If your Eng partner says pages can’t be calculated, pagination will use only arrow-left and arrow-right icon buttons to navigate to either the Next or Previous page.
Interactions > Pagination >Unknown Pages

Lazy loading

  • To show the initial number of rows and wait to show more until the user or browser needs them, select lazy loading.

Pagination is vertical, and includes only one Load more button instead of Previous and Next navigation or page numbers.

Interactions > Pagination > Lazy Loading


Reordering functionality is built in. In addition to drag-and-drop, users can manually control the order using the action menu and they can use the keyboard to control row order.

  • Users can use the drag-and-drop handle to change row order on the active page of the data table.
Interactions > Reordering
  • Users can use their keyboard to reorder rows.
Interactions > Reordering Keyboard
  • Users can use menu items in the actions menu to move data to first or last priority, or change its priority number.
Interactions > Reordering Menu


  • Note: If the known number of pages can’t be calculated, the last priority can’t be set because it’s unknown.


  • Priority can be set to also reorder rows and their data. Users can also set priority during data creation. For example, when adding a user.




Batch actions

A user can perform an action on multiple rows at the same time. Designers can customize the batch actions so they’re appropriate for the data. For example, Delete selected rows.

  • After a selection is made using a checkbox, the available actions appear above the data table.
  • When used in a paginated data table, the Select all option can affect only the rows in the current page or affect all the data in the table. Work with your engineers to choose which action is best for your data.
Batch Actions

Single-record actions

Use when you need single-record actions.

  • The actions are placed inline within a row.
  • Include a recommended maximum of two inline icon buttons to avoid having too many elements competing with the data. If more inline actions are needed, use an overflow menu to contain all of the actions.
Single-record actions


Odyssey components are designed and built to meet accessibility requirements out of the box. So, designers and engineers can focus on any accessibility concerns unique to their problem areas.

Our components meet WCAG 2.2 AA criteria and WAI-ARIA guidelines to provide a usable and accessible experience to everyone. See the ARIA guidelines for table.

Content guidelines


  • Concisely describe the data table using a recommended maximum of seven words or less.
  • Explain what the data has in common and what purpose it serves in the UI.
  • Write in sentence case (capitalize the first word and proper nouns only).
  • Don’t use punctuation.
  • If the entire page is a data table, the page title can function as the title.

Description (Optional)

  • A description can be added under the title to provide more information about the data or its source.
  • Keep the description to two sentences or less.
  • Use end punctuation if the description uses complete sentences.


  • Explain what the data table is about for users with accessibility devices.
  • Keep the description to two sentences or less.
  • Use end punctuation if the caption uses complete sentences.

Filter labels

  • Try to limit the number of categories and their options. Filters should help users feel in control, not overwhelm them.
  • Order the options in a logical way that makes sense to users. For example, display quantitative amounts in ascending or descending order.
  • Make labels, especially within categories, as parallel and consistent as possible.
  • Use each filter only once.
  • Use sentence case.
  • Don’t use punctuation
  • Default filter labels: Apply, Select all, Clear all

Column header

  • Describe the data in the column in one to two words.
  • Use the first column for your most important data. Include lower priority data toward the end.
  • Use nouns or short noun phrases.
  • Try to limit headers and cell content to ~45 characters maximum.
  • If applicable, include units of measurement as symbols.
  • Write in sentence case (capitalize the first word and proper nouns only).
  • Don’t use punctuation.
  • Don’t use icons alone.
  • Alignment is the same as the data alignment in cells.

Pagination label

By page

Label the pagination Previous and Next. Or, provide ALT labels for the icons.

Lazy loading

If we can’t provide specific numbers or results, use a label of Load more.

Interactions > Pagination > Lazy Loading

Error message

An error message is served when the table can’t be displayed.

Default error messages


Due to a technical issue, the data couldn’t be loaded. Try refreshing the page.


Data couldn’t be loaded

The data couldn't be loaded due to a technical issue. Try refreshing the page.


See Errors

Data variant content types


  • Be concise and scannable.
  • Try to limit labels and cell content to ~45 characters.
  • Write in sentence case (capitalize the first word and proper nouns only).
  • By default, styling is what is most legible and scannable for text.
  • If a cell is empty, use an en dash (–) to indicate this.


  • Don’t repeat units of measurement symbols, for example %. Instead, specify them in the column header.
  • Use the same number of decimal places for numbers per column.
  • If a cell is empty, use an en dash (–) to indicate this.


  • Hide status labels.
  • Use a clear column heading.


  • For readability, don’t wrap dates.
  • If a cell is empty, use an en dash (–) to indicate this.
  • Use consistent US numerical date format (Month, Date, Year or MM/DD/YYYY); it will be localized for each country or region. See Grammar and mechanics.


  • Buttons are only icons.
  • See button.



Content accessibility

Titles and captions

Each data table should have both a title and a caption.


  • The visible heading of the data table.
  • A concise, descriptive title tells users the purpose of the data table or summarizes the data it contains.


  • Visually hidden description of the data table.
  • Captions help users of assistive technologies find the data table, understand what it's about, and decide if they want to read it.

Column header

  • Required for each column to meet accessibility standards.

ARIA labels

Use the same text as the title, description, column headers, and row headers.


Figma: Table

Figma guide

General guidance


Data table presets

To select one of several commonly used data table presets:

  1. Within .Table container, click on Table.
  2. Set the Layout preset to any of the available options.

If you need to customize your own data table, select All features enabled to start and work backwards. See Activate specific table features.


Table density

To make the data table itself more or less dense in terms of vertical padding per row:

  1. Within .Table container, click on Table.
  2. Set the Density to Default, Expanded, or Condensed.



To indicate that a data table has expanded beyond the max width of the viewport and requires horizontal scrolling:

  1. Select Table and stretch it to the right as desired.
    1. The data table should be cropped on the right side by the edge of the .Table container.
  2. Under table surface, show the .Table-overflow-indicator layer.
  3. Under the properties panel, select Scrollbar position and set it to either left, centered, or right.


Increase or decrease amount of visible columns

  1. Select Row Content under Table > .Row > Top for all .Rows and .Header.
  2. Under the properties panel, set Columns to the number of columns needed.
  3. To speed up this process, Command+Shift+Click on a single instance of row content (typically text) for each .Row and the .Header.
    1. Then press the Backslash three times to arrive at the Row Content layer for all selected rows simultaneously.

Data table header

Tips and things to avoid

  • The data table header is a .Row sub-component, just like all the data table rows below it. As such, it has the same property toggles as all other .Rows, some of which aren’t relevant.
  • For the .Header, do not activate Expanded or change Density to anything but Small. Doing so will change the header to a regular row.
  • Every other option can be adjusted, and should be adjusted to align with rows below it. For example, if all rows in the data table have Is draggable activated, the header should as well so that columns between the header and rows below will be aligned spatially.


Column (width) resize indicator

  1. To indicate that columns can be resized, click on the column title .cell-content and select all column titles in the header.
  2. In the properties panel, set Show column resize grip to active.


Column sort indicator

  1. To indicate that a column is being sorted, click on the column title .cell-content.
  2. In the properties panel, set Show sort arrow to active.
    1. Choose from any of the available options under the Sort direction dropdown:
    2. When sort is descending, use arrow-down.
    3. When sort is ascending, use arrow-up.
    4. When a sortable column title is being hovered, select arrow-unsorted and color it Neutrals/600.

Data table rows

Increase or decrease amount of visible rows

  1. Select Table and hide or show the number of .Rows you want.


Activate specific data table features

If no data table preset has the exact combination of features you need (see Data table presets), you may make your own combination:

  1. Under the Table layer, select all .Rows including the .Header and hidden .Rows as well.
  2. In the properties panel, activate or deactivate Is draggable, Has checkbox, Is expandable, Has numbered rows, Has delete, and/or Has actions.


Change the state of a row

  1. Under the Table layer, select the applicable .Row.
  2. In the properties panel, set the State to the setting you need: Default, Hover, or Selected.

Avoid using the Header setting for any row other than the header.


Expanded rows

For rows that are expandable and need to be displayed as expanded:

  1. Select the applicable .Rows.
  2. In the properties panel, set Expanded to active.
  3. Ensure you have selected all .Rows, including .Header, and set Is expandable to active.
  4. Select the expanded .Rows, click .Content placeholder.
  5. In the properties panel, swap the instance with your custom content.


Numbered rows (column width variance)

There are three options available for the width of the numbered column. These sizes are to ensure consistent spacing per row in the event that the design requires either no column title (just numbered rows), a short column title, or a longer column title. To adjust:

  1. Select .cell content of all .Rows, (including those that are hidden) and .Header.
  2. Under Layer > Properties panel > Table dropdown, select from any of the available sizes.


Known or unknown total number of pages

Many Okta UIs have technical constraints that make calculating and displaying the total number of pages impossible. If your Eng partner says pages can’t be calculated:

  1. Select .Table-pagination.
  2. Under the properties panel, select Page quantity.
  3. Set it to Hide.


Multi-level dropdown


  1. Select filter menu button.
  2. In the properties panel, change State to Expanded multi-level.

This can also be collapsed again. For table filtering, do not use any other Button type or the State of Expanded.


Multi-level menu item state

  1. In Menu list, select .multi-level item.
  2. In the properties panel, change State to Hover or Selected.
    1. If you need to show the secondary level expanded, ensure the Selected state is active.


Increase or decrease amount of visible menu items

  1. Select Menu list and hide or show the number of .Multi-level item’s you want.
  2. Ensure the bottom .Multi-level item has Is last item toggled on in the properties panel so that a divider line isn’t visible at the bottom of the menu.


Expand secondary level

  1. Select filter menu button.
  2. In the properties panel, toggle on Secondary selection menu expanded.


Change secondary level type

  1. Select Selection menu.
  2. In the properties panel, choose from the options available under Type: Select, Checkbox, Radio, or Input.

Displaying active filters

Activate filters row

  1. To indicate that there are active filters, select the .Search-actions-filters row.
  2. In the properties panel, set the Show Filters row to Active.


Increase or decrease amount of active filters

  1. Select Filters row and hide or show the number of Tags you want.
  2. Ensure all filters are set to is Removable.