Table
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.
| 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.
| 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!
| 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.
| 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.
| Planet | Radius (km) | Type | Gravity (g) | Perihelion date | Base status | Travel | |
|---|---|---|---|---|---|---|---|
| Jupiter | 69,911 | Gas giant | 27.94 | January 21, 2023 |
| ||
| Earth | 6,371 | Terrestrial | 1.00 | January 2, 2021 |
| ||
| Mercury | 1,737 | Terrestrial | 0.37 | – |
|
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.
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.
Statuses
No extra styling is required when adding Statuses to your table. Ensure their labels are hidden and their column has an appropriate heading.
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.
Empty cells
If a cell is empty, use an en dash (–) to indicate this.
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.
# Basic usage
| Planet | Radius (km) | Type | Perihelion date |
|---|---|---|---|
| Jupiter | 69,911 | Gas giant | January 21, 2023 |
| Earth | 6,371 | Terrestrial | January 2, 2021 |
| Mercury | 1,737 | Terrestrial | – |
<figure class="ods-table--figure">
<figcaption class="ods-table--figcaption">
Big and small planets
</figcaption>
<table class="ods-table">
<caption>Information about the largest and smallest planets.</caption>
<thead>
<tr>
<th scope="column">Planet</th>
<th scope="column" class="is-ods-table-num">Radius (km)</th>
<th scope="column">Type</th>
<th scope="column" class="is-ods-table-date">Perihelion date</th>
</tr>
</thead>
<tbody>
<tr>
<td>Jupiter</td>
<td class="is-ods-table-num">69,911</td>
<td>Gas giant</td>
<td class="is-ods-table-date">January 21, 2023</td>
</tr>
<tr>
<td>Earth</td>
<td class="is-ods-table-num">6,371</td>
<td>Terrestrial</td>
<td class="is-ods-table-date">January 2, 2021</td>
</tr>
<tr>
<td>Mercury</td>
<td class="is-ods-table-num">1,737</td>
<td>Terrestrial</td>
<td class="is-ods-table-date">–</td>
</tr>
</tbody>
</table>
</figure>
# Row headings
| Planet | Radius (km) | Type | Perihelion date |
|---|---|---|---|
| Jupiter | 69,911 | Gas giant | January 21, 2023 |
| Earth | 6,371 | Terrestrial | January 2, 2021 |
| Mercury | 1,737 | Terrestrial | – |
<figure class="ods-table--figure">
<figcaption class="ods-table--figcaption">
Big and small planets
</figcaption>
<table class="ods-table">
<caption>Information about the largest and smallest planets.</caption>
<thead>
<tr>
<th scope="column">Planet</th>
<th scope="column" class="is-ods-table-num">Radius (km)</th>
<th scope="column">Type</th>
<th scope="column" class="is-ods-table-date">Perihelion date</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Jupiter</th>
<td class="is-ods-table-num">69,911</td>
<td>Gas giant</td>
<td class="is-ods-table-date">January 21, 2023</td>
</tr>
<tr>
<th scope="row">Earth</th>
<td class="is-ods-table-num">6,371</td>
<td>Terrestrial</td>
<td class="is-ods-table-date">January 2, 2021</td>
</tr>
<tr>
<th scope="row">Mercury</th>
<td class="is-ods-table-num">1,737</td>
<td>Terrestrial</td>
<td class="is-ods-table-date">–</td>
</tr>
</tbody>
</table>
</figure>
# Row grouping
| Type | Planet | Radius (km) | Descriptor | Perihelion date |
|---|---|---|---|---|
| Gas giants | Jupiter | 69,991 | Jovian | January 21, 2023 |
| Saturn | 58,232 | Saturnian | November 29, 2032 | |
| Terrestrial | Earth | 6,371 | Terran | January 2, 2021 |
| Venus | 6,052 | Venusian | – | |
| Mars | 3,389 | Martian | August 3, 2020 |
<figure class="ods-table--figure">
<figcaption class="ods-table--figcaption">
Big and small planets
</figcaption>
<table class="ods-table">
<caption>Information about some of the largest and smallest planets.</caption>
<thead>
<tr>
<th scope="column">Type</th>
<th scope="column">Planet</th>
<th scope="column" class="is-ods-table-num">Radius (km)</th>
<th scope="column">Descriptor</th>
<th scope="column" class="is-ods-table-date">Perihelion date</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row" rowspan="2">Gas giants</th>
<td>Jupiter</td>
<td class="is-ods-table-num">69,991</td>
<td>Jovian</td>
<td class="is-ods-table-date">January 21, 2023</td>
</tr>
<tr>
<td>Saturn</td>
<td class="is-ods-table-num">58,232</td>
<td>Saturnian</td>
<td class="is-ods-table-date">November 29, 2032</td>
</tr>
<tr>
<th scope="row" rowspan="3">Terrestrial</th>
<td>Earth</td>
<td class="is-ods-table-num">6,371</td>
<td>Terran</td>
<td class="is-ods-table-date">January 2, 2021</td>
</tr>
<tr>
<td>Venus</td>
<td class="is-ods-table-num">6,052</td>
<td>Venusian</td>
<td class="is-ods-table-date">–</td>
</tr>
<tr>
<td>Mars</td>
<td class="is-ods-table-num">3,389</td>
<td>Martian</td>
<td class="is-ods-table-date">August 3, 2020</td>
</tr>
</tbody>
</table>
</figure>
# Empty tables
| Planet | Radius (km) | Type | Perihelion date |
|---|---|---|---|
| Aw beans. This set of filters didn't return any results. | |||
<figure class="ods-table--figure">
<figcaption class="ods-table--figcaption">
Big and small planets
</figcaption>
<table class="ods-table" data-null>
<caption>Information about the largest and smallest planets.</caption>
<thead>
<tr>
<th scope="column">Planet</th>
<th scope="column" class="is-ods-table-num">Radius (km)</th>
<th scope="column">Type</th>
<th scope="column" class="is-ods-table-date">Perihelion date</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="4">
Aw beans. This set of filters didn't return any results.
</td>
</tr>
</tfoot>
</table>
</figure>
# Checkboxes
| Planet | Radius (km) | Type | Perihelion date | |
|---|---|---|---|---|
| Jupiter | 69,911 | Gas giant | January 21, 2023 | |
| Earth | 6,371 | Terrestrial | January 2, 2021 | |
| Mercury | 1,737 | Terrestrial | – |
<figure class="ods-table--figure">
<figcaption class="ods-table--figcaption">
Big and small planets
</figcaption>
<table class="ods-table">
<caption>Information about the largest and smallest planets.</caption>
<thead>
<tr>
<th scope="column" class="is-ods-table-checkbox">
<input class="ods-checkbox is-ods-checkbox-indeterminate" type="checkbox" name="row[all]" id="checkbox-all" value="check-all" checked>
<label class="ods-checkbox--label" for="checkbox-all">
<span class="u-visually-hidden">Select all rows</span>
</label>
</th>
<th scope="column">Planet</th>
<th scope="column" class="is-ods-table-num">Radius (km)</th>
<th scope="column">Type</th>
<th scope="column" class="is-ods-table-date">Perihelion date</th>
</tr>
</thead>
<tbody>
<tr>
<td class="is-ods-table-checkbox">
<input class="ods-checkbox" type="checkbox" name="row[0]" id="checkbox-0" value="check-0" checked>
<label class="ods-checkbox--label" for="checkbox-0">
<span class="u-visually-hidden">Select this row</span>
</label>
</td>
<td>Jupiter</td>
<td class="is-ods-table-num">69,911</td>
<td>Gas giant</td>
<td class="is-ods-table-date">January 21, 2023</td>
</tr>
<tr>
<td class="is-ods-table-checkbox">
<input class="ods-checkbox" type="checkbox" name="row[1]" id="checkbox-1" value="check-1">
<label class="ods-checkbox--label" for="checkbox-1">
<span class="u-visually-hidden">Select this row</span>
</label>
</td>
<td>Earth</td>
<td class="is-ods-table-num">6,371</td>
<td>Terrestrial</td>
<td class="is-ods-table-date">January 2, 2021</td>
</tr>
<tr>
<td class="is-ods-table-checkbox">
<input class="ods-checkbox" type="checkbox" name="row[2]" id="checkbox-2" value="check-2" checked>
<label class="ods-checkbox--label" for="checkbox-2">
<span class="u-visually-hidden">Select this row</span>
</label>
</td>
<td>Mercury</td>
<td class="is-ods-table-num">1,737</td>
<td>Terrestrial</td>
<td class="is-ods-table-date">–</td>
</tr>
</tbody>
</table>
</figure>
# Sorting Table
| Jupiter | 69,911 | Gas giant | January 21, 2023 |
| Earth | 6,371 | Terrestrial | January 2, 2021 |
| Mercury | 1,737 | Terrestrial | – |
<figure class="ods-table--figure">
<figcaption class="ods-table--figcaption">
Big and small planets
</figcaption>
<table class="ods-table">
<caption>Information about the largest and smallest planets.</caption>
<thead>
<tr>
<th scope="column">
<button class="ods-table--sort is-ods-table-unsorted">Planet</button>
</th>
<th scope="column" class="is-ods-table-num">
<button class="ods-table--sort is-ods-table-desc">Radius (km)</button>
</th>
<th scope="column">
<button class="ods-table--sort is-ods-table-unsorted">Type</button>
</th>
<th scope="column" class="is-ods-table-num">
<button class="ods-table--sort is-ods-table-unsorted">Perihelion date</button>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Jupiter</td>
<td class="is-ods-table-num">69,911</td>
<td>Gas giant</td>
<td class="is-ods-table-date">January 21, 2023</td>
</tr>
<tr>
<td>Earth</td>
<td class="is-ods-table-num">6,371</td>
<td>Terrestrial</td>
<td class="is-ods-table-date">January 2, 2021</td>
</tr>
<tr>
<td>Mercury</td>
<td class="is-ods-table-num">1,737</td>
<td>Terrestrial</td>
<td class="is-ods-table-date">–</td>
</tr>
</tbody>
</table>
</figure>