Table

A table shows information in columns and rows.

Maturity level - ready for production

View the React component implementation details and all variants in Storybook.

Tables help logically organize information and group like things together, and they make it easier to understand complex content, as explained on plainlanguage.gov. They’re especially useful for showing long lists of sequential or structured content. Users read tables one row or column at a time, making it easy to digest and compare information.

Tables also help users find specific information within a large data set. For example, if someone is looking for how much their tax is based on their income for a particular year, it’s much easier to find the intersection of that year and income range than to scan or read an entire paragraph of text.


Component examples

Default


Guidance

When to use the table component

  • Displaying tabular data. When you need to display tabular information, such as statistical data.

  • Displaying directories. When listing locations or resources that have similarly structured content for many items.

When to consider something else

  • Non-tabular data. Depending on the type of content, consider using other presentation formats, such as definition lists or hierarchical lists.

  • Robust data visualization. If you need to display more complex relationships or data visualizations, consider a bar graph, infographic, or other type of chart.

  • Dashboards and other layouts. Don’t use tables in place of a layout grid. Table content should follow a consistent structure using headers and logical columns and rows.

  • Long-form content. Table cell content should be brief and scannable. If you find yourself drafting multiple bullet points or paragraphs within a single table cell, the content is likely better off under conventional page headers or in an accordion.

  • Groups of items with different structures. Consider a list or cards for content items that don’t follow a consistent pattern.

Usability guidance

  • Keep it simple. Tables are great at displaying data and complex information. Minimal visual styling helps surface this information more easily.

  • Always use a header row. Use plain language and short labels to define the type of information that can be found in each column or row. For more complex table structures, review the WCAG accessibility recommendations for tables.

  • Predictably format columns. Take care not to vary units or formatting within the same column. Instead, normalize values so they can be easily compared. For example, if most of the rows in a table show a count in days, don’t have some rows that count by weeks.

  • Right-align numerical data. Align numbers that represent a sum to the right using the text alignment utilities on the table cells.

  • Use a monospace font for numerical data. For even better readability of dense, numerical data, consider formatting numbers that convey amounts, such as percentages, currency, or tallies, in a monospace font. (There’s no need to apply monospace formatting or alignment to phone numbers, zip codes, dates, or other number content that can’t be totaled.)

  • Attribute table data in a caption. If your table includes information from a specific source or contains frequently updated content, provide the source and/or last updated date. This clarification is especially useful if your table summarizes data from a more extensive source.

  • Consider a small-screen experience. On mobile devices and other small screens, numerical data across many columns can be easier to understand if the table scrolls horizontally. Directory lists are more readable if the rows display in a stacked layout. For tables with more than two columns, make sure you choose either a scrollable or a stacked variant.

  • Minimize the number of columns. It’s easier for users to read down a long list of rows than it is to read across a long list of columns. Eliminate columns when possible, or consider swapping the columns and rows to improve scannability.

  • Enable sort where useful. Add row sorting to individual columns of long tables where the data can be logically ordered either alphabetically or numerically.

  • Don’t use row sorting with merged cells. Sorting won’t work properly if your table contains colspan or rowspan attributes on the cells.

  • Don’t use row sorting with the mobile stacked variants. Sorting won’t work properly with these variants because the column headers at the top of the table don’t appear at narrow widths and are instead moved into the cell content in each row.


Accessibility

  • Simple tables can have up to two rows of headers. Each header cell should have scope="col" or scope="row".

  • Complex tables have more than two levels of headers. Each header should have a unique id and each data cell should have a headers attribute with each related header cell’s id listed.

  • Add title and attribution in a caption. When adding a title, attribution, or a last-updated date to a table, include it in the <caption> tag inside of the <table> element.

  • Add an aria-live region to the page when enabling row sorting. An aria-live region immediately following the <table> element automatically announces when the sort state changes for visitors using screen readers, but it must be added to the HTML document before load: <div class="usa-sr-only usa-table__announcement-region" aria-live="polite"></div>

  • Don’t add aria-label attributes to sortable column headers. Enabling row sorting automatically adds aria-label attributes to the sortable column headers and their toggle sort buttons via JavaScript. These labels are updated to reflect each column’s current sort state (ascending, descending, or unsorted) whenever sort changes.

  • Scrollable tables need to be focusable. When you use the .usa-table-container--scrollable variant with a table, you must add the tabindex="0" attribute to the scrollable element. This attribute assures that users navigating with a keyboard are able to select and scroll the table. tabindex="0" enables focus on elements that do not get focus by default. This attribute does not change the tab order. It places the element in the logical navigation flow.

Using the table component

  • Enable row sorting on columns with sortable data. To activate row sorting, add the data-sortable attribute to the table header element (<th>) of any column with sortable data, and insert an element with the aria-live="polite" attribute and the class ".usa-table__announcement-region" immediately following the table.

  • Set a default sort column and direction. To sort a table’s rows by a specific sortable column on load, add the attribute aria-sort equal to a sort direction, such as “ascending” or “descending,” to that column header as in the following example: <th data-sortable aria-sort="ascending" scope="col">.

  • Provide raw values for cells with formatted number content. If you have formatted your cell content for display (such as using percent, currency, or comma formatting) or if your cell content is non-numeric but should be sorted in a numeric order (such as months, days of the week, or dates), provide a numeric-sortable value in a data-sort-value attribute on each table cell. Examples follow:

    • Numbers with currency or comma formatting:

      <td data-sort-value="132773.54"> $132,773.54 </td>

    • Percentages or fractions, converted to decimal:

      <td data-sort-value="0.943"> 94.3% </td>

    • Months, weekdays, or other orderable text:

      <td data-sort-value="2"> February </td>

    • Dates, in Unix timestamp:

      <td data-sort-value="327092400"> Aug. 21, 1959 </td>

    • File sizes, in bytes:

      <td data-sort-value="1126501"> 1.1MB </td>

Table variants

Variant Description
usa-table–borderless Removes the outer table borders, retaining only a single bottom border on each row. Best for tables with more text than numbers.
usa-table–compact Reduces the row height and vertical spacing to display more table rows within a limited space. Should only be used with dense, numerical data, not text content. Pairs well with scrollable and striped variants, but is not suitable for use with stacked variants.
.usa-table-container–scrollable > .usa-table Add the usa-table-container–scrollable class to a container around any usa-table to apply a horizontal scrollbar if the columns exceed the available width. Ideal for dense tables with many columns.
usa-table–stacked Stacks the table cells on narrow screens. Ideal for tables that contain more text information than numerical data. If you use this variant, you must ensure there is a data-label attribute on each cell of the table that matches the column header.
usa-table–stacked-header Stacks the table cells on narrow screens and visually promotes the first cell of every row into a “header” for that group. Preferred for directories and other lists where the first cell of every row is a name. If you use this variant, you must ensure there is a data-label attribute on each cell of the table that matches the column header.
usa-table–striped Applies alternating horizontal striping to help the eye track across table rows. Pairs well with the scrollable variant for tables with many columns.

External References

For usage and accessibility guidelines please refer to the USWDS.