Add header cells to tables

Applicable Role(s): Content Creator, Developer

Overview

Table headers tell users which data cells are related to that topic. This makes it easier to understand how table data is structured, especially if using assistive technology to navigate a table.

Best Practices

  • Table headers are designated with a table header element (<th>).
  • Use scopes to indicate whether the header is a column header or row header.
    • For column headers, the scope is "column" (<th scope="col">).
    • For row headers, the scope is "row" (<th scope="row">).
  • The headers should be visually distinguishable from the data cells, like using a different background and font color and/or bolding the header text
  • Empty cells in the header row must be marked as a data cell <td> instead of <th>.

Pattern Examples

Column headers

In Drupal:

Table properties in Drupal highlighting first row headers

Code


<table>
<caption>Columnar headers
example</caption>

<thead>
<tr>
  <th scope="col">Header 1</th>
  <th scope="col">Header 2</th>
</tr>
</thead>

<tbody>
<tr>
  <td>Data1</td>
  <td>Data2</td>
</tr>
</tbody>

</table>

Rendered Table

Columnar headers example
Header 1 Header 2
Data1 Data2

Row Headers

In Drupal:

Table properties showing first column headers

Code


<table>
<caption>Row headers 
example</caption>


<tbody>
  <tr>
    <th scope="row">Row Header</th>
    <td>Data1</td>
    <td>Data2</td>
  </tr>
  <tr> 
    <th scope="row">Row Header</th> 
    <td>Data1</td> 
    <td>Data2</td> 
  </tr>
</tbody>

</table>

Rendered Table

Row headers example
Row Header Data1 Data2
Row Header Data1 Data2

Column and Row Headers

In Drupal:

Table properties showing both row and column headers selected

Code



<table>
 <caption>Delivery slots:</caption>
    <tr>
      <td></td>
      <th scope="col">Monday</th>
      <th scope="col">Tuesday</th>
      <th scope="col">Wednesday</th>
      <th scope="col">Thursday</th>
      <th scope="col">Friday</th>
    </tr>
    <tr>
      <th scope="row">09:00 - 11:00</th>
      <td>Closed</td>
      <td>Open</td>
      <td>Open</td>
      <td>Closed</td>
      <td>Closed</td>
    </tr>
    <tr>
      <th scope="row">11:00 - 13:00</th>
      <td>Open</td>
      <td>Open</td>
      <td>Closed</td>
      <td>Closed</td>
      <td>Closed</td>
    </tr>
    […]
</table>

Rendered Table

Delivery slots:
  Monday Tuesday Wednesday Thursday Friday
09:00 - 11:00 Closed Open Open Closed Closed
11:00 - 13:00 Open Open Closed Closed Closed

Table with colgroup (needs manual markup)

Code

<table>
  <col>
  <colgroup span="2"></colgroup>
  <colgroup span="2"></colgroup>
  <tr>
    <td rowspan="2"></td>
    <th colspan="2" scope="colgroup">Mars</th>
    <th colspan="2" scope="colgroup">Venus</th>
  </tr>
  <tr>
    <th scope="col">Produced</th>
    <th scope="col">Sold</th>
    <th scope="col">Produced</th>
    <th scope="col">Sold</th>
  </tr>
  <tr>
    <th scope="row">Teddy Bears</th>
    <td>50,000</td>
    <td>30,000</td>
    <td>100,000</td>
    <td>80,000</td>
  </tr>
  <tr>
    <th scope="row">Board Games</th>
    <td>10,000</td>
    <td>5,000</td>
    <td>12,000</td>
    <td>9,000</td>
  </tr>
</table>

Rendered Table

  Mars Venus
Produced Sold Produced Sold
Teddy Bears 50,000 30,000 100,000 80,000
Board Games 10,000 5,000 12,000 9,000

Table example borrowed from the Web Accessibility Initiative's (WAI's) tables tutorial page.

 

In Wordpress:

  • Select the Table widget from the blocks editor pallette.  Select number of rows and columns.  Be sure to include the header row in the row count.

Wordpress Table component create wizard showing number of columns and rows.

 

Wordpress table with Header and rows and columns showing data.
  •  Edit the table as "HTML" so we can set the scope of the header cells:

Edit As Html menu option
  •  Add "scope"attributes, depending on if your header cells are rendered horizontally (scope="col") or vertically (scope="row"):

Highlighted header cells with scope set to 'col'