Tables
Use tables to display tabular data only, never for layout!
Jump to a component:
Basic tables
Most tables on the website are basic tables.
Styling
Table headings have gray shading (column headings are slightly darker than row headings), and there is a light gray divider between all table cells. Table text is slightly smaller than body text.
Responsive behavior for Basic tables
Tables aren’t truly responsive. Once the screen becomes too narrow for the table, a shadow appears along the left and right sides, showing users that there’s more of the table off the screen that they can scroll horizontally to see.
That said, tables don’t break the responsive layout or let the text flow outside the table cells.
How to use for Basic tables
Using tables in WordPress requires a plugin. Get approval from the Web Team to use it.
The plugin lets editors insert a table with a certain number of rows and columns; merge or split table cells; add or remove table rows; copy, cut, or paste table rows; and add table headings.
Development info for Basic tables
Stylesheet location:
/_source/styles/components/_tables.scss
Javascript adds the wrapper and shadow divs for responsiveness – don’t add them manually.
Captions
- All forms should have a
<caption>
, which provides an accessible description of the table contents.- You can use
<caption class="visually-hide">
if you don’t want the caption to be visible. - Captions can have a Font Awesome icon before the text, right after the opening
<caption>
tag. <table summary="">
is deprecated, use<caption>
instead.
- You can use
Accessibility
- All forms should have a
<thead>
that contains the column headings and a<tbody>
that contains the rest of the form cells (<tfoot>
is optional). - All column and row headings should use the table header tag (
<th>
), and include eitherscope="col"
orscope="row"
depending on the header type. - Don’t ever leave the first column heading blank, even if there are row headings. This is bad for accessibility.
- Don’t add other style elements to the table cells, such as
valign
,width
,height
,bgcolor
, orstyle=""
.
<table> <caption>Caption</caption> <!-- optional: class="visually-hide" --> <thead> <tr> <th scope="col">Column heading</th> <th scope="col">Column heading</th> </tr> </thead> <tbody> <tr> <th scope="row">Row heading</th> <!-- or td with data if no row headings --> <td>Data</td> </tr> ... </tbody> <tfoot> <!-- optional --> <th scope="row">Footer heading</th> <!-- or td with data if no footer heading --> <td>Data</td> </tfoot> </table>
Example of Basic tables
This example includes an optional footer.
Column heading | Column heading | Column heading | Column heading | Column heading | Column heading |
---|---|---|---|---|---|
Row heading | Data | Data | Data | Data | Data |
Row heading | Data | Data | Data | Data | Data |
Footer heading | Data | Data | Data | Data | Data |
Sortable tables
Use a sortable table if you need the table data to be able to sort by column.
Styling
Same as basic tables, but an up/down arrow is added after each table heading.
How to use for Sortable tables
Same as basic tables. See “development info” for how to make the table sortable.
Note: If the table has a footer, the footer cells won’t be included in the sorting.
Development info for Sortable tables
Stylesheet location:
/_source/styles/components/_tables.scss
Javascript adds the wrapper and shadow divs for responsiveness – don’t add them manually.
<table class="turntable"> <caption>Caption</caption> <!-- optional: class="visually-hide" --> <thead> <tr> <th scope="col">Column heading</th> <th scope="col">Column heading</th> </tr> </thead> <tbody> <tr> <th scope="row">Row heading</th> <!-- or td with data if no row headings --> <td>Data</td> </tr> ... </tbody> </table>
Example of Sortable tables
Column heading | Column heading | Column heading |
---|---|---|
Row heading 1 | Data 1 | Data 1 |
Row heading 2 | Data 2 | Data 2 |
Row heading 3 | Data 3 | Data 3 |
Tables with a visible caption
All tables should have a caption that provides an accessible description of the table contents, but the caption can either be visible or visually hidden.
Styling
Same as basic tables, but with a row directly above the table headers that displays the caption. Captions can have a Font Awesome icon before the text.
How to use for Tables with a visible caption
Same as basic tables. See “development info” for how to add a visible caption.
Development info for Tables with a visible caption
Stylesheet location:
/_source/styles/components/_tables.scss
<table class="turntable"> <caption><i class="fa-solid fa-icon-name">Caption</caption> <!-- optional icon --> <thead> <tr> <th scope="col">Column heading</th> <th scope="col">Column heading</th> </tr> </thead> <tbody> <tr> <th scope="row">Row heading</th> <!-- or td with data if no row headings --> <td>Data</td> </tr> ... </tbody> </table>
Example of Tables with a visible caption
Column heading | Column heading | Column heading | Column heading |
---|---|---|---|
Row heading | Data | Data | Data |
Row heading | Data | Data | Data |
Row heading | Data | Data | Data |
Tables with zebra stripes
Large or complex tables can benefit from zebra striping, which makes it easier to distinguish one row from the next and to follow the data from one column to the next.
Styling
Same as basic tables, but every other row has a slightly darker background.
How to use for Tables with zebra stripes
Same as basic tables. See “development info” for how to add zebra striping.
Development info for Tables with zebra stripes
Stylesheet location:
/_source/styles/components/_tables.scss
Normal tables just need <table class="zebra">
. For tables with rowspans, use <table class="zebra zebra-complex">
and add <tr class="zebra-darker">
on the rows that should be the dark stripes. The light stripes don’t need anything extra.
Normal: <table class="zebra"> <caption>Caption</caption> <!-- optional: class="visually-hide" --> <thead> <tr> <th scope="col">Column heading</th> <th scope="col">Column heading</th> </tr> </thead> <tbody> <tr> <th scope="row">Row heading</th> <!-- or td with data if no row headings --> <td>Data</td> </tr> ... </tbody> </table> With rowspans: <table class="zebra zebra-complex"> <caption>Caption</caption> <!-- optional: class="visually-hide" --> <thead> <tr> <th scope="col">Column heading</th> <th scope="col">Column heading</th> <th scope="col">Column heading</th> <th scope="col">Column heading</th> </tr> </thead> <tbody> <tr class="zebra-darker"> <th rowspan="2" scope="row">Row heading 1</th> <td>Data 1.1</td> <td>Data 1.1</td> <td>Data 1.1</td> </tr> <tr class="zebra-darker"> <td>Data 1.2</td> <td>Data 1.2</td> <td>Data 1.2</td> </tr> <tr> <th rowspan="2" scope="row">Row heading 2</th> <td>Data 2.1</td> <td>Data 2.1</td> <td>Data 2.1</td> </tr> <tr> <td>Data 2.2</td> <td>Data 2.2</td> <td>Data 2.2</td> </tr> </tbody> </table>
Example of Tables with zebra stripes
Column heading | Column heading | Column heading | Column heading |
---|---|---|---|
Row heading 1 | Data 1 | Data 1 | Data 1 |
Row heading 2 | Data 2 | Data 2 | Data 2 |
Row heading 3 | Data 3 | Data 3 | Data 3 |
Row heading 4 | Data 4 | Data 4 | Data 4 |
If the table has rowspans, you’ll need to hardcode the stripes:
Column heading | Column heading | Column heading | Column heading |
---|---|---|---|
Row heading 1 | Data 1.1 | Data 1.1 | Data 1.1 |
Data 1.2 | Data 1.2 | Data 1.2 | |
Row heading 2 | Data 2.1 | Data 2.1 | Data 2.1 |
Data 2.2 | Data 2.2 | Data 2.2 | |
Row heading 3 | Data 3.1 | Data 3.1 | Data 3.1 |
Data 3.2 | Data 3.2 | Data 3.2 | |
Row heading 4 | Data 4.1 | Data 4.1 | Data 4.1 |
Data 4.2 | Data 4.2 | Data 4.2 |