Accessible Tables
Since tables are used to organize large bits of data it’s very important to structure the table correctly. We need to use proper syntax for assistive technology such as screen or brail readers, which means we’ll use <td>
, <th>
, and scope
as needed. We also need to style tables in such a way that the organization and relationships are obvious to users with no assistive technology. Generally, that means that the <th>
and <td>
elements are styled differently. These items combined will make an accessible table.
Basic Rules
<th>
elements should never be empty.- Use colspan and rowspan to expand cells as needed
- Be sure to wrap rows inside of
<thead>
,<tbody>
, or<tfoot>
unless using<col>
and<colgroup>
. You can use both.
Captions
Captions are not required, but they are very helpful, especially when the tables are very complicated. Captions are simple to use. It doesn’t matter where you place the caption because it’s position, top or bottom, is determined by CSS.
<table>
<caption>My pets</caption>
<!-- rows/columns here -->
</table>
Dogs | Cats | Turtles |
---|---|---|
Pugsley | Sandi | Yertle |
Wednesday | Peppi | Gimpy |
Felicity Smoak | Speedy |
To change the position of the caption you can change the CSS property caption-side
to be either top
or bottom
.
caption {
caption-side: top;
}
Summary
If you find that a simple caption is not enough, and you need a longer description, you can use aria-describedby
or a figure
.
Using aria-describedby:
<p id="table-description">This is a long description for the table that is both visual, and accessible to those with assistive technology.</p>
<table aria-describedby="table-description"></table>
Using figures:
<figure>
<figcaption>
<strong id="table-caption">Caption Title</strong><br>
<span id="table-summary">This is a long description for the table that is both visual, and accessible to those with assistive technology.</span>
</figcaption>
<table aria-labeledby="table-caption" aria-describedby="table-summary"></table>
</figure>
Headers
Basic tables with simple headers
If the table has one row of headers across the top, or one column of headers on the left, then you only need to use the standard <th>
element for those headers.
<table class="table">
<thead>
<tr>
<th>Dogs</th>
<th>Cats</th>
<th>Turtles</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pugsley</td>
<td>Sandi</td>
<td>Yertle</td>
</tr>
<tr>
<td>Wednesday</td>
<td>Peppi</td>
<td>Gimpy</td>
</tr>
<tr>
<td></td>
<td>Felicity Smoak</td>
<td>Speedy</td>
</tr>
</tbody>
</table>
Tables with two headers
Now that we’re introducing multiple headers, we’ll need to start adding a scope to the <th>
elements.
<table class="table text-white">
<caption>Shirt Stock</caption>
<thead>
<tr>
<td></td>
<th scope="column">SM</th>
<th scope="column">MD</th>
<th scope="column">LG</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Yellow Shirt</th>
<td>1</td>
<td>3</td>
<td>2</td>
</tr>
<tr>
<th scope="row">Black Shirt</th>
<td>0</td>
<td>6</td>
<td>8</td>
</tr>
<tr>
<th scope="row">Teal Shirt</th>
<td>9</td>
<td>9</td>
<td>9</td>
</tr>
</tbody>
</table>
Multiple headers
This table is a little more complicated so we’re going to ditch the <thead>
and <tbody>
elements and use <col>
and <colgroup>
instead. We can still use both, but it isn’t necessary.
<table class="table text-white">
<caption>Company Years Experience</caption>
<col>
<colgroup span="3"></colgroup>
<colgroup span="3"></colgroup>
<tr>
<td rowspan="2"></td>
<th colspan="3" scope="colgroup">Frontend</th>
<th colspan="3" scope="colgroup">Backend</th>
</tr>
<tr>
<th scope="col">HTML</th>
<th scope="col">CSS</th>
<th scope="col">JS</th>
<th scope="col">PHP</th>
<th scope="col">Python</th>
<th scope="col">SQL</th>
</tr>
<tr>
<th scope="row">Mathew</th>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<th scope="row">Mark</th>
<td>24</td>
<td>15</td>
<td>10</td>
<td>9</td>
<td>2</td>
<td>15</td>
</tr>
<tr>
<th scope="row">Luke</th>
<td>20</td>
<td>3</td>
<td>20</td>
<td>0</td>
<td>0</td>
<td>20</td>
</tr>
</table>