Skip header information, go directly to contentWeb Accessibility Center home page. Web-AIM tutorials. Web Accessibility in Mind (Web-AIM) home page.

Return to Tutorials List

How to Create Accessible Tables

skip the list of pages in this documentPrevious Page | page 1 | page 2 | page 3 |

Data Tables

Data tables are different from layout tables. The purpose of data tables is to present information in a grid, or matrix, and to have column or rows that show the meaning of the information in the grid. When screen readers read straight through data tables--especially large ones--it's easy for users to get lost. Let's go to an an example. Rather than let you see the table, let's see if you can understand it by listening to it through a screen reader. Choose a format: wav | real | mp3.

Like I said, it's easy to get lost. You can't tell which information goes with which heading. You want to see what the table looks like? Alright, let's take a look at the table.

In all fairness, I should say that screen readers can enter a "table reading mode" if the user wishes to. In this mode, the user can navigate through each data cell one at a time. Still, without proper markup, there is no way to tell which headings go with which data cells. We'll come back to this table later.

When the proper HTML markup is in place, users of screen readers can navigate through data tables one cell at a time, and they will hear the column and row headers spoken to them.

Designate row and column headers using the <th> tag.

The very first step toward creating an accessible data table is to designate row and/or column headers. This is easy enough to do. Most authoring tools provide a method of changing data cells into header cells. In the markup, the <td> tag is used for table data cells and the <th> tag is used for table header cells. Going back to our original data table example, the column headers for this table are "Name," "Age," and "Birthday." The row headers are "Jackie' and "Beth."

Shelly's Daughters
Name Age Birthday
Jackie 5 April 5
Beth 8 January 14

Associate the data cells with the appropriate headers.

Now that we've created headers, we need to associate the cells with the appropriate headers. Unfortunately, there aren't many tools that will do this for you. You have to go into the markup and do it yourself. There are two ways to do associate data cells with their headers.

1. Scope

The scope attribute should be used on simple data tables such as the one in this example. Here is the markup for the table, using the scope attribute:

<table border="1" align="center">
<caption>Shelly's Daughters</caption>
<tr>
<th scope="col">Name</th>
<th scope="col">Age</th>
<th scope="col">Birthday</th>
</tr>
<tr>
<th scope="row">Jackie</th>
<td>5</td>
<td>April 5</td>
</tr>
<tr>
<th scope="row">Beth</th>
<td>8</td>
<td>January 14</td>
</tr>
</table>

The scope tag tells the browser and screen reader that everything under the column is related to the header at the top, and everything to the right of the row header is related to that header. It's a straightforward concept.

2. Headers and "id"

Another way to accomplish the same purpose is to use the "headers" and "id" attributes. The markup looks like this:

<table border="1" align="center">
<caption>Shelly's Daughters</caption>
<tr>
<th id="name">Name</th>
<th id="age">Age</th>
<th id="birthday">Birthday</th>
</tr>
<tr>
<th id="jackie">Jackie</th>
<td headers="age jackie">5</td>
<td headers="birthday jackie">April 5</td>
</tr>
<tr>
<th id="beth">Beth</th>
<td headers="age beth">8</td>
<td headers="birthday jackie">January 14</td>
</tr>
</table>

This method is more complex. It should be used with tables of a more complex nature, where the scope attribute will not work.

Use proportional sizing, rather than absolute sizing.

The rule that applies to layout tables also applies to data tables. Let the browser window determine the width of the table whenever possible, to reduce the horizontal scrolling required of those with low vision.

Provide names or titles for data tables using the <caption> tag.

Tables ought to have some sort of title or caption to them. This is properly done by using the caption tag, right after the opening <table> tag, like this:

<table border="1" align="center">
<caption>Shelly's Daughters</caption>
. . .

Provide summaries using the summary attribute.

This guideline is not a requirement for simple tables, but can greatly increase the comprehension of more complex tables. A complex table of weather data might have a summary that says:

"A warming trend has been observed in Cache Valley, with temperatures about 5 degrees above historical averages over the last two months, with the highest temperature difference being 25 degrees above average."

Such a description would highlight the important elements of a table, and help the user to know what to look for in the data.

Avoid spanned rows or columns.

I wish that I could tell you that all screen readers do exactly what they're supposed to. Unfortunately, one of the most popular screen readers on the market, JAWS, does not read the tables with spanned cells well at all, even when correct markup is used to associate data cells with their corresponding headers. As it turns out, JAWS handles spanned rows in tables very poorly. The above table uses spanned rows in two instances: for the two cells on the left which contain the department codes BIO and BUS (which stand for biology and business, by the way). JAWS gets very confused with these spanned rows, and actually associates the WRONG headers with the data cells below. This means that the user will hear such nonsensical things as "Room number: Tue, Thu" and "Days: 11:00."

Don't despair. There are things that can be done to avoid totally confusing the users of screen readers, even if they are only work-arounds to make up for the programming deficits in JAWS.

Work-around #1

Make duplicate cells within the table, rather than one single row-spanned cell. See what workaround #1 would look like.

Work-around #2

We could also combine the first two columns into one. See what workaround #2 would look like.

Avoid tables with more than two levels of row and/or column headers.

There are methods of marking up tables of greater complexity than those discussed here. Some screen readers can read this markup and render the content accurately. The sad truth is that the most popular screen reader, JAWS, cannot do so reliably. If at all possible, use simple, one- or two-dimensional tables without spanned rows or columns. That is the safest bet.

Top of Page || Return to Tutorials List

This Tutorial is reproduced on this site with the kind permission of WebAIM. For additional information and resources on web accessibility please visit http://www.webaim.org.

© Copyright 2000-2001 WebAIM. All Rights Reserved. Terms of Use.