Article: Making Data Tables Accessible
The first step towards making data tables accessible is to use existing tags such as th, td and new HTML 4 tags such as caption and summary correctly. When used as intended these tags will provide valuable meta information about your table. You should use the following tags to indicate the type of content contained with a table cell:
- th for headers
- td for data.
- caption to give your table a short title - indicating the tables contents.
The summary attribute can also be used to provide a verbose description of the purpose of the table - to help someone who is using a voice or Braille browser. It can also be used to help explain the information within a table if it is of a particularly complex nature. I have seen examples of the summary attribute being used to re-state the entire contents of a table - as an alternative to providing a link to a single column version on another page.
Here is a simple example:
| Jim | Pat | John | |
|---|---|---|---|
| Favourite colour | Green | Turquoise | Yellow |
| Favourite Pastime | Photography | Swimming | Badminton |
Here is what the HTML looks like:
<caption>Jim, Pat and John's favourite things</caption>
<tr>
<th></th>
<th>Jim</th>
<th>Pat</th>
<th>John</th>
</tr>
<tr>
<th>Favourite colour</th>
<td>Green</td>
<td>Turquoise</td>
<td>yellow</td>
</tr>
<tr>
<th>Favourite pastime</th>
<td>photography</td>
<td>swimming</td>
<td>badmington</td>
</tr>
</table>
The summary attribute is not visible to those using standard GUI (Graphical User Interface) Web browsers - but can be used by assistive technologies such as screen and braille readers.
It is probably not a good idea to put a summary attribute into every table in your layout as many layouts consist of lots of tables within tables. If you are feeling queasy about the fact that your Web page will not pass the 'Bobby' test because you have not put summaries in all of your tables (apart from the main table) it might be a better idea to add a short summary such as 'Layout table' or put the summary attribute in but leave it empty.
Headers are by default center aligned within table cells. I am not sure if this is why so many people ignore the TH tag and use the TD tag for their headers instead - but if that is the case it is worth noting that aligning headers is a simple matter. Ideally Cascading Style Sheets (CSS) should be used to align headings left or right - but the align attribute also works with the TH element, e.g.
<th align="left" style="text-align: left">Jim</th>
I have used CSS within the element to illustrate this point - but it is better to set the style attributes in an external style sheet or one within the header of the document. This ensures that users with their own style sheet will be able to over-ride your preferences.
If you are using style sheets to set the attributes for your table you can still leave in the old style attributes. Your style sheet will override the values of the table attributes as will the style sheet used by a visitor to your site. The older style attributes should ensure that your table still looks good in the browsers that do not support style sheets.
On a related note, do not use TH as a way of making text within a normal data cell bold and centered - use TD and provide appropriate presentation markup - preferably using a style sheet.
Making Complex Tables Accessible
So far, in relation to data tables, everything has been straightforward; nothing mentioned so far to strain your cerebral cortex too much. The accessibility problems really begin when we are dealing with more complex tables, those with many rows and columns. The critical issue is how we ensure that the relationships between the table headers and the table data remains clear to someone using a simple screen reader or braille display.
If you are a sighted user this is a fairly simple procedure; you look at the header and scan down the column - or along the row - to read off the data associated with that header. Having said that, as someone who occasionally attempts to teach students statistics, I have noticed that even for sighted users interpreting tables is not always a simple exercise - but we will convieniently ignore that fact for the moment.
As we now know access technologies such as screen readers or braille displays tend to read the data in tables a row at a time, left to right across the page. In a table with many columns and many rows this can present a major problem, i.e. trying to remember which header matches up with which particular piece of data. Once you go beyond the first couple of rows - this can become extremely difficult.
Here is an example of a table showing Cascading Style Sheet bugs in Internet Explorer 5x compiled by CSS Pointers Group at http://css.nu/pointers/bugs.html. The original table at has 13 rows - I have just extracted the first five rows for illustrative purposes.
| CSS Property/ Problem | Description | Workaround | Notes/Footnotes |
|---|---|---|---|
| absolute/relative positioning | absolute child loses position | set the width property of the parent element | W demo |
| Classes set as number (i.e. P.1) | recognized due to error-recovery | Illegal syntax; don't use | W95, NT (6) |
| color | f0f0f0 rendered | illegal syntax; include the required '#' | W95,NT |
| width on body is ignored | ignored | use width on DIV instead | W95, NT |
Use of the id and headers attribute
Try this exercise - hide the column headers in the table above, by placing a ruler or piece of paper over them - and gradually work your way down the table reading out the contents of each cell. If you are anything like me you will begin to feel anxious about what each cells represents. As a sighted person I can keep glancing up the column to reassure myself of the nature of the information I am reading. If I am using a screen reader or a braille display this is not an option open to me.
To help with this problem HTML 4 provides new attributes; id, headers and scope.
id and headers
By giving each table heading a unique label (using the 'id' attribute) - and then associating each of the data cells with that label, using the 'header' attribute, new Web browsers can give appropriate feedback for those using assistive technologies.
An example should make this clearer: Here is how the HTML looks for the above table using the 'id' attribute in the headers and the 'header' attribute in each of the data cells.
<CAPTION style="font-size: 120%; font-style: bold">Workarounds for CSS bugs with Internet Explorer 5x, (W=Win '95 M=Mac)</CAPTION>
<tr>
<th id="header1">CSS Property/ Problem</TH>
<TH id="header2">Description</TH>
<TH id="header3">Workaround</TH>
<TH id="header4">Notes/Footnotes</TH>
</tr>
<tr>
<td headers="header1">absolute/relative positioning</TH>
<td headers="header2"> absolute child loses position</td>
<td headers="header3"> set the width property of the parent element</td>
<td headers="header4">W demo<</td>
</tr>
<tr>
<td headers="header1">Classes set as number (i.e. P.1)</td>
<td headers="header2">recognized due to error-recovery</td>
<td headers="header3">Illegal syntax; don't use</td>
<td headers="header4">W95, NT (6)</td>
</tr>
<tr>
<td headers="header1">color</td>
<td headers="header2">f0f0f0 rendered</td>
<td headers="header3">illegal syntax; include the required '#'</td>
<td headers="header4">W95,NT</td>
</tr>
<tr>
<td headers="header1">width on body is ignored</td>
<td headers="header2"> ignored</td>
<td headers="header3">use width on DIV instead</td>
<td headers="header4"> W95, NT</td>
</tr>
</table>
A screen reader will read out the first data row as follows:
CSS Property/ Problem: absolute/relative,
Description: absolute child loses position,
Workaround: set the width property of the parent element,
Notes/Footnotes: W demo
And the second row:
CSS Property/ Problem: Classes set as number (i.e. P.1),
Description: recognized due to error-recovery,
Workaround: Illegal syntax; don't use,
Notes/Footnotes: W95, NT (6)
And so on.
SCOPE
The 'headers' attribute works even when table headings are not aligned logically with the data cells they apply to. i.e. when headers and the corresponding data are not part of the same column or row.
For simple tables, where the column or row headers do correspond, the id/headers pair can be replaced with the 'scope' attribute. The scope attribute can have a value of 'col', 'row', colgroup or rowgroup. When using SCOPE with the value of 'col' (i.e scope ="col") - you are saying to the browser (or relevant user agent) ' everything in this column relates to this heading. An example should make this clear:
Using the first two data rows from the previous table, 'scope' is used as follows:
<caption style="font-size: 120%; font-style: bold">Workarounds for CSS bugs with Internet Explorer 5x, (W=Win '95 M=Mac)</CAPTION>
<tr>
<th scope="col">CSS Property/ Problem</th>
<th scope="col">Description</th>
<th scope="col">Workaround</th>
<th scope="col">Notes/Footnotes</th>
</tr>
<tr>
<td>absolute/relative positioning</th>
<td> absolute child loses position</td>
<td> set the width property of the parent element</td>
<td>W demo<</td>
</tr>
<tr>
<td>Classes set as number (i.e. P.1)</td>
<td>recognized due to error-recovery</td>
<td>Illegal syntax; don't use</td>
<td>W95, NT (6)</td>
</tr>
</table>
More advanced uses of the scope attribute can be found on the World Wide Web Consortiums Website at: http://www.w3.org/TR/REC-html40/struct/tables.html#h-11.4
The ABBR attribute
The techniques above are great for those using non graphical browsers - but they throw up a problem of their own. If the headings in the table are very long it can become a bit tiring to keep having the text read out over and over again for each cell. The answer is to provide an abbreviation to substitute for the long heading. The 'abbr' attribute does this and is used in the following way:
<TH id="header1" abbr="Property">CSS Property/ Problem</TH>
The first instance of the heading will be read out in full, but subsequent instances will be substituted by the abbreviation, in this case the word 'Property'. This saves time and some more’ brain cycles’ in the process.
Further HTML 4 Techniques
With the introduction of HTML 4 and HTML 4.01 the W3C group 'sought remedies for a number of authoring habits that cause problems for users'. One way they did this was to encourage authors to make a clearer separation between document structure and presentation. New elements were added that would further clarify the structure of Web documents.
New elements added include, the axis attribute, col, colgroup, thead, tbody, and tfoot divisions. col and colgroup are poorly implemented in current browsers so I don't advocate their immediate use. Further information about new elements and their use can be found at: http://www.w3c.org
thead, tbody, and tfoot
thead, tbody, and tfootT - in line with the goals of HTML - add further structure to HTML Tables by given information about what parts of the Web page constitute the headers and footers. Browsers can display those headers and footers continuously - while the body of the table scrolls. This is very useful for devices that have small screens such as Palm Pilots or Web connected telephones. These are not yet supported by all common browsers.
The thead and tfoot contain the table row that holds the identifying labels for the table's columns. tbody contains the actual rows of data. Even though tfoot will appear at the bottom of the table, the W3C HTML 4 standard specifies that it should be specified immediately after thead and before tbody. This allows a part of the table to be displayed quickly - as the 'user agent' does not need to read the entire table before it can display the first screen.
E.g.
<thead>
<tr>
<th>table Header
</th>
</tr>
</thead>
<tfoot>
<tr>
<td>Footer
</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>First row
</td>
</tr>
<tr>
<td>Second Row
</td>
</tr>
</tbody>
</table>
Specifying the tfoot before the tbody causes problems for browsers that do not support the tfoot tag such as versions of Netscape, earlier than version 6. When the tfoot tag is not recognised the footer information will be displayed incorrectly, i.e. at the top of the table just below the table header. If you would like to use the tfoot tag the best workaround for this is to specify the TFOOT after the tbody tag - despite the fact that this goes against the current standard.
AXIS
The axis attribute is a more sophisticated version of the 'headers' attribute - and can show relationships between groups of cells anywhere in the table. For those coding tables by hand the axis attribute will not - I fear - be heavily used because it is a bit of a brain twister to set up. Only when this new technique finds its way in into WYSWYG Web design applications will we start to see it more often on Web pages. An explanation of the 'axis' attribute with an example can be found on the Web Review site (http://www.webreview.com/2001/04_27/webauthors/index04.shtml).
One final thought worth mentioning for the sake of completeness: You should avoid using the pre element for tabular layout of data - the correct use of the table element is prefered as it allows assistive technologies to take advantage of the table accessibility features.
Some thoughts on data tables
New tags introduced by HTML 4 provide valuable structure to data tables and their use helps to increase the accessibility of data table for both people using access technologies and those using the proliferation of new Internet connected technologies - particularly those with small screens, or hands free operation. However, many tags are still poorly implemented on current browsers (e.g col and colgroup) - so a pragmatic approach is required.
