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.
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 either scope="col" or scope="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, or style="".
<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.

Regular table
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
Sortable table
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
clock Table 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
Table 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:

Complex table with zebra 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