How can data tables be made accessible?

Data tables are tables that are used to represent actual tabular data, with rows and columns of related information. The technique for creating an accessible data table depends on the complexity of the table. Data tables can be described as either simple, complex (layered), or irregular. A simple data table is one in which each cell corresponds with only one column header and/or one row header. In contrast, a complex data table is one in which there are nested columns or nested rows, and consequently cells within the table correspond with multiple column and/or row headers. Without accessible markup complex tables can be challenging if not impossible for screen reader users to understand.

For all data tables regardless of complexity, table headers should be explicitly identified as table headers using the <th> element. It is also desirable for all tables to use the <caption> element to briefly describe the content of the table. Tables may also use the "summary" attribute, but this is recommended for tables that are more complex in nature and contain many types of data. It is important to know that the content of captioned tables is generally viewable above the table in a browser, while the content of the summary attribute is not visible in browser -this content is generally available to screen readers.

Accessible Techniques

Identify headers in data tables

Table headers should be used to develop a relationship between table header cells and table data cells. Identify table headers by using the th (table header) element in place of the td (table cell) element. Note that table headings will automatically bold and center, which can be reversed or styled through your stylesheet.

<table cellpadding="0" cellspacing="0" border="1">
<tr>
<th>Company Name</th>
<th>Company City</th>
<th>Phone Number</th>
</tr>
<tr>
<td>Thorton Electric</td>
<td>San Diego</td>
<td>415-555-1212</td>
</tr>
<tr>
<td>Wilson Window</td>
<td>Phoenix</td>
<td>602-555-1212</td>
</tr>
</table>
Company Name Company City Phone Number
Thorton Electric San Diego 415-555-1212
Wilson Window Phoenix 602-555-1212

In the simplified example above, a screen reader parsing the contents of this table would read out to the user something like: "Company Name: Thorton Electric, Company City: San Diego, Phone Number: 415-555-1212, Company Name: Wilson Window...". As explained earlier, a table's headers cells should be marked up properly to generate a relationship between their corresponding data cells.

Use table captions to briefly describe the content of a data table

Much in the same way that Alt text is used to describe an image, table captions should be used to summarize the contents of a data table. To use captions, the <caption> tag should be used, and it must be placed after the opening <table> tag. Using the previous example we apply captions in the following manner:

Code View:

<table cellpadding="0" cellspacing="0" border="1">
<caption>Table 1. Company Data</caption>
<tr>
<th>Company Name</th>
<th>Company City</th>
<th>Phone Number</th>
</tr>...

Screen View:

Table 1. Company Data
Company Name Company City Phone Number
Thorton Electric San Diego 415-555-1212
Wilson Window Phoenix 602-555-1212

If a description of the subject of a data table precedes the table, the use of captions is not required. Like table headings, CSS can be used to style the table captions in anyway you'd like.

Use of the Summary Attribute

For more complex tables where a short description will not suffice, use the summary attribute of the <table> element to provide more description of the table's content:

<table summary="The name, city, phone number of companies in the North-West">

Unlike the <caption> tag, the content of the table summary cannot be viewed in visual browsers so avoid use of the summary attribute for simplified tables. In addition, make sure the description is detailed enough for screen reader users to understand the purpose of the table.

For complex (layered) tables, use the scope attribute in conjunction with table headers to link headers to data

To illustrate, we are going to remove the "Company Name" header from the Company Data table example and will instead use the data cells in the first column (company names) as headings. We will then apply the scope attribute to all header cells:

Code View:

<table cellpadding="0" cellspacing="0" border="1">
<caption>Table 1. Company Data</caption>
<tr>
<td></td>
<th scope="col">Company City</th>
<th scope="col">Phone Number</th>
</tr>
<tr>
<th scope="row">Thorton Electric</th>
<td>San Diego</td>
<td>415-555-1212</td>
</tr>
<tr>
<th scope="row">Wilson Window</th>
<td>Phoenix</td>
<td>602-555-1212</td>
</tr>
</table>

Screen View:

Table 1. Company Data
Company City Phone Number
Thorton Electric San Diego 415-555-1212
Wilson Window Phoenix 602-555-1212

By providing a scope attribute to our table column and row header cells, we are providing guidance to screen readers and non-visual browsers of what heading or headings apply to data cells. This is an example of a complex data table. Priority 1 Guideline, Checkpoint 5.2 reads:

"For data tables that have two or more logical levels of row or column headers, use markup to associate data cells and header cells. "

Complex (layered) Tables

Tables that have two or more logical levels of row or column headers (also known as layered tables), you may use id and headers markup to link headers to data. By assigning each header a unique id, you can associate two or more header attributes to each cell by manually entering all related header id's, separated by spaces, to each cell.

Code View:

<table summary="The name and city of each company and the number of male and female employees in each company" border="1" cellspacing="0" cellpadding="0">
<caption>Table 1. Company Data</caption>
<tr>
<td rowspan="2"></td>
<th colspan="2" id="employees">Employees</th>
<th rowspan="2" id="city">City</th>

</tr>
<tr>
<th id="males">Males</th>
<th id="females">Females</th>

</tr>
<tr>
<th id="thorton electric">Thorton Electric</th>
<td headers="thorton electric employees males">325</td>
<td headers="thorton electric employees females">412</td>
<td headers="thorton electric city">San Diego</td>

</tr>
<tr>
<th id="wilson">Wilson Window</th>
<td headers="wilson employees males">1220</td>
<td headers="wilson employees females">1401</td>
<td headers="wilson city">Phoenix</td>

</tr>
</table>

Screen View:

Table 1. Company Data
Employees City
Males Females
Thorton Electric 115 112 San Diego
Wilson Window 122 35 Phoenix

It is important to note that this technique is easy to make errors in while coding so if possible use the scope technique if the table design permits.

Excellent tutorials on accessible table markup are available in the Access Board's Guide to the 508 Standards and in WebAIM's two-part tutorial Creating Accessible Tables.