Skip to main content

Table

Component status:Ready
A table is used to display tabular data in rows and columns.

A table is used to display repeating data with the same structure efficiently across rows and columns so that it can be easily scanned and compared. Tables should never take the place of columns within a page layout.

Examples#

Default#

Default Table

Optional summary of data table. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Column 1Column 2Column 3
Cell data A1Cell data B1Cell data C1
Cell data B1Cell data B2Cell data B3
Cell data C1Cell data C2Cell data C3

Some info about this default table.

<table class="bux-table" aria-describedby="summary-default">
<caption>Default Table</caption>
<thead>
<tr>
<th scope="col">Column 1</th>
<th scope="col">Column 2</th>
<th scope="col">Column 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell data A1</td>
<td>Cell data B1</td>
<td>Cell data C1</td>
</tr>
<tr>
<td>Cell data B1</td>
<td>Cell data B2</td>
<td>Cell data B3</td>
</tr>
<tr>
<td>Cell data C1</td>
<td>Cell data C2</td>
<td>Cell data C3</td>
</tr>
</tbody>
</table>

<p id="summary-default" class="visually-hidden"> Some info about this default table.</p>

Striped Table#

Striped Table
Column 1Column 2Column 3
Cell data A1Cell data B1Cell data C1
Cell data B1Cell data B2Cell data B3
Cell data C1Cell data C2Cell data C3

Some info about this striped table.

<table class="bux-table bux-table--striped" aria-describedby="summary-striped">
<caption>Striped Table</caption>
<thead>
<tr>
<th scope="col">Column 1</th>
<th scope="col">Column 2</th>
<th scope="col">Column 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell data A1</td>
<td>Cell data B1</td>
<td>Cell data C1</td>
</tr>
<tr>
<td>Cell data B1</td>
<td>Cell data B2</td>
<td>Cell data B3</td>
</tr>
<tr>
<td>Cell data C1</td>
<td>Cell data C2</td>
<td>Cell data C3</td>
</tr>
</tbody>
</table>

<p id="summary-striped" class="visually-hidden"> Some info about this striped table.</p>

Compact Table#

Compact Table
Column 1Column 2Column 3
Cell data A1Cell data B1Cell data C1
Cell data B1Cell data B2Cell data B3
Cell data C1Cell data C2Cell data C3

Some info about this compact table.

<table class="bux-table bux-table--compact" aria-describedby="summary-compact">
<caption>Compact Table</caption>
<thead>
<tr>
<th scope="col">Column 1</th>
<th scope="col">Column 2</th>
<th scope="col">Column 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell data A1</td>
<td>Cell data B1</td>
<td>Cell data C1</td>
</tr>
<tr>
<td>Cell data B1</td>
<td>Cell data B2</td>
<td>Cell data B3</td>
</tr>
<tr>
<td>Cell data C1</td>
<td>Cell data C2</td>
<td>Cell data C3</td>
</tr>
</tbody>
</table>

<p id="summary-compact" class="visually-hidden"> Some info about this compact table.</p>

Table with column and row headers#

Table with column and row headers
Column 1Column 2Column 3
Row ACell data B1Cell data C1
Row BCell data B2Cell data B3
Row CCell data C2Cell data C3

Some info about this table with two headers.

<table class="bux-table" aria-describedby="summary-two-headers">
<caption>Table with column and row headers</caption>
<thead>
<tr>
<th scope="col">Column 1</th>
<th scope="col">Column 2</th>
<th scope="col">Column 3</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Row A</th>
<td>Cell data B1</td>
<td>Cell data C1</td>
</tr>
<tr>
<th scope="row">Row B</th>
<td>Cell data B2</td>
<td>Cell data B3</td>
</tr>
<tr>
<th scope="row">Row C</th>
<td>Cell data C2</td>
<td>Cell data C3</td>
</tr>
</tbody>
</table>

<p id="summary-two-headers" class="visually-hidden"> Some info about this table with two headers.</p>

Sortable Table#

Sortable Table
Cell data A1Cell data B1Cell data C1
Cell data B1Cell data B2Cell data B3
Cell data C1Cell data C2Cell data C3

Some info about this sortable table.

<table class="bux-table bux-table--sortable" aria-describedby="summary-sortable">
<caption>Sortable Table</caption>
<thead>
<tr>
<th scope="col" class="sort-by"><button aria-pressed="false">Column 1</button></th>
<th scope="col" class="sort-by"><button aria-pressed="false">Column 2</button></th>
<th scope="col" class="sort-by"><button aria-pressed="false">Column 3</button></th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell data A1</td>
<td>Cell data B1</td>
<td>Cell data C1</td>
</tr>
<tr>
<td>Cell data B1</td>
<td>Cell data B2</td>
<td>Cell data B3</td>
</tr>
<tr>
<td>Cell data C1</td>
<td>Cell data C2</td>
<td>Cell data C3</td>
</tr>
</tbody>
</table>
<div class="bux-table bux-table--sortable bux-table--announcement-region" aria-live="polite"></div>

<p id="summary-sortable" class="visually-hidden"> Some info about this sortable table.</p>

Usage#

Dos#

  • Use a table for complex tabular data that needs to be scanned and/or compared
  • Use the simplest configuration possible

Don’ts#

  • Don’t use if page structure is needed, reference the Grid
  • Don’t use if it is a list with no comparisons, use a List Component
  • Don’t use if the data set is small and only has a title and description, use a Description List
  • Don’t use to control the layout of text on a page that is not tabular data

Implementation Notes#

Table variants can be combined by adding multiple modifier classes. The following example code will produce a striped table that is also compact.

<table class="bux-table bux-table--striped bux-table--compact"></table>

Accessibility#

  • Give your table a meaningful caption. Change the default value of the caption element to text that clearly describes the type of data being presented by the table.
  • 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 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.
  • 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.
  • Web Accessibility in Mind Table Details

References#