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:
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:
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:
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.