Making accessible tables

Navigation

Skip navigation.

Site search

Site navigation

Article links

Introduction

Most of us are aware of the problems that table based layouts can cause. They make it hard or costly to rebrand or restructure. They make pages overly large, costing more in bandwidth charges, and making it difficult for people on slow connections to load the page. And more importantly, they make pages very hard to navigate for blind/visually impaired, or disabled users, as the table structures don't make much sense when not displayed in a visual context. And many of us have managed to get away from tables for our layouts.

But the thing is that tables were invented for a reason. For displaying tabular data. A set of results, or a comparison table, or anything else that when displayed belongs in a table.

Since we still need to use tables occasionally, we also need a way of making sure that the tables still make sense to our blind/visually impaired, or disabled visitors. As most data tables contain a large amount of data, we need some way to help them understand what bit of data belongs where.

Take this basic table. In a visual environment, the visual positioning of the data would make enough sense for most of us to understand.

<table>
	<tr>
		<td rowspan="2">Browsers</td>
		<td rowspan="2">Op</td>
		<td colspan="2">Gecko</td>
		<td rowspan="2">Saf</td>
		<td rowspan="2">IE</td>
	</tr>
	<tr>
		<td>FF</td>
		<td>Moz</td>
	</tr>
	<tr>
		<td>Browser</td>
		<td>Yes</td>
		<td>Yes</td>
		<td>Yes</td>
		<td>Yes</td>
		<td>Yes</td>
	</tr>
	<tr>
		<td>Email</td>
		<td>Yes</td>
		<td>No</td>
		<td>Yes</td>
		<td>No</td>
		<td>No</td>
	</tr>
	<tr>
		<td>IRC</td>
		<td>Yes</td>
		<td>No</td>
		<td>Yes</td>
		<td>No</td>
		<td>No</td>
	</tr>
</table>
BrowsersOpGeckoSafIE
FFMoz
BrowserYesYesYesYesYes
EmailYesNoYesNoNo
IRCYesNoYesNoNo

If a blind person were to read this with a Braille reader, or with a speech reader, it would appear like this:
Browsers Op Gecko Saf IE FF Moz Browser Yes Yes Yes Yes Yes Email Yes No Yes No No IRC Yes No Yes No No.

Clearly this would be no help at all. So we need to make the structure more obvious. So there is something that the Braille or speech reader can identify and hopefully convay some meaning to the user.

Many speech readers are available for general screen reading (JAWS and Dragon Naturally Speaking are popular ones, and the Mac Operating System has its own inbuilt screen reader). New to the field but with a distinct difference is Opera 7.6+. Unlike the releases for other platforms, the Windows 2000/XP release is able to receive spoken commands and read normal web pages. But what makes it unique is that not only can it interact with VoiceXML pages, but it can also understand speech and aural CSS.

Unfortunately, because of this different focus, Opera does not immediately make use of the accessibility features of tables, but because of Opera's high level of CSS support, you can use CSS to allow it to make use of them. Since I am sure you probably don't want to have to go to all that work yourself, I have done all the work for you. This page is fitted with my speech enabled 'Spoken Table' stylesheet. Feel free to download it and use it on your own pages or as a user stylesheet, subject to my usual terms of use. Opera 7.6+ users, you can enable it right now using View - Style - Spoken Table.

Table Headings

The first thing to do is to make all headings obvious. This is as simple as replacing all <td> tags with <th> tags on heading cells.

<th>Browser</th>
<td>Yes</td>
<td>Yes</td>
BrowsersOpGeckoSafIE
FFMoz
BrowserYesYesYesYesYes
EmailYesNoYesNoNo
IRCYesNoYesNoNo

Heading scope

Although this has little or no effect in a visual environment, a Braille or speech reader can use this information to tell the user if this heading is a row heading or column heading. This in turn will enable them to make more sense of the rest of the table.

<th scope="row">Browser</th>
<td>Yes</td>
<td>Yes</td>
BrowsersOpGeckoSafIE
FFMoz
BrowserYesYesYesYesYes
EmailYesNoYesNoNo
IRCYesNoYesNoNo

Heading titles

I have used abbreviations in the table headings. Seeing this in a visual context, these may make sense. They are unlikely to make so much sense in a non-visual environment. Adding a title attribute allows the Braille or speech reader to explain what the abbreviation means. As an extra bonus, the title is usually shown by visual browsers when the user holds their mouse cursor over the header.

<th title="Internet Relay Chat" scope="row">IRC</th>
<td>Yes</td>
<td>No</td>
BrowsersOpGeckoSafIE
FFMoz
BrowserYesYesYesYesYes
EmailYesNoYesNoNo
IRCYesNoYesNoNo

Heading abbreviation

This attribute provides an appropriate abbreviation of the heading, if the heading is significantly long. The abbreviation can be used instead of the normal heading content to save space in visual tables, or inserted before all applicable data cells by a speech or Braille reader to make it more clear which header they relate to.

I have seen this abused (and even recommended) as a way to say the full header content if the header content itself is abbreviated. That is not the right way to do it. If the header content is an abbreviation, you should use the title attribute to explain it. The abbr attribute should only be used to provide an appropriate abbreviation of a header.

Note: My stylesheet does not make use of these, and will use the full header content instead. As a result, I will not use this attribute in any further examples, but you may still want to use it if it is appropriate for your tables. Other speech readers (such as Home Page Reader) will use this abbreviation if it is provided.

<th abbr="W3C">World Wide Web Consortium</th>

Captions and summaries

The caption is typically used to label the table, giving a quick title in both visual and non-visual browsers. For non-visual browsers, it is also useful to provide a table summary. This enables the user to read or hear a description of the information that the table will provide, so that they can easily tell if they want to skip that table and continue beyond it. Something most visual based users take for granted.

<table summary="A list of the most common browsers detailing what other application components they contain">
<caption>Table 5 - browser components</caption>
Table 5 - browser components
BrowsersOpGeckoSafIE
FFMoz
BrowserYesYesYesYesYes
EmailYesNoYesNoNo
IRCYesNoYesNoNo

id and headers attributes

If we assign an ID to each heading, then we can set the headers attribute on the table cells. This allows a Braille or speech reader to not only give the contents of the cell, but also say what headings it applies to. More advanced readers will be able to say the associated header content, but some will only be able to say the contents of the headers attribute, so try to make sure that the IDs make sense on their own. To keep your document valid, the IDs should be unique within your document. Since I am repeating my example, I have not done this, so this document will not validate.

<th id="Opera" title="Opera" scope="col" rowspan="2">Op</th>
...
<th id="Browser" title="Web browser" scope="row">Browser</th>
<td headers="Opera Browser">Yes</td>
Table 6 - browser components
BrowsersOpGeckoSafIE
FFMoz
BrowserYesYesYesYesYes
EmailYesNoYesNoNo
IRCYesNoYesNoNo

Categories

Sometimes, table contents fit into categories that cannot be easily defined within the column structure. Each table cell or heading may accept the axis attribute. In theory this could be queried, giving a summary of information within the given category. However, since most browsers have no way of displaying this except using scripts, I do not recommend its use. However, Braille or speech readers may have a way to read it, so you can still use it if you want to.

<th axis="Internet suite" id="Opera" title="Opera" scope="col" rowspan="2">Op</th>
Table 7 - browser components
BrowsersOpGeckoSafIE
FFMoz
BrowserYesYesYesYesYes
EmailYesNoYesNoNo
IRCYesNoYesNoNo

thead, tbody and tfoot

Splitting a table heading up into sections has numerous purposes. Visual browsers are allowed to scroll table bodies while leaving the header and footer in place on the page. The header and footer can be printed on each page of a printed table spanning multiple pages. But more usefully for accessibility, it helps a Braille or speech reader identify whether the current block of data is the header section, body section or footer section of the table. Just one more way to help non-visual users make sense of tables.

(Unfortunately, Opera makes the small mistake here of reading the summary after reading the table when using my Spoken Table stylesheet. This is due to a bug with generated content positioning. I have reported it, so hopefully it will be fixed soon.)

<thead>
	<tr> ... </tr>
	     ...
</thead>
<tbody>
	<tr> ... </tr>
	     ...
</tbody>
Table 8 - browser components
BrowsersOpGeckoSafIE
FFMoz
BrowserYesYesYesYesYes
EmailYesNoYesNoNo
IRCYesNoYesNoNo

To summarise ...

Including all of these techniques would probably be going a little overboard, but the more you can use, the easier you will make things for visitors who are unable to use a visual medium for viewing web pages. You can use my 'Spoken Table' stylesheet to make it even easier for them to make sense of the table confusion. If you are a user who has accessibility problems with tables, you can use my stylesheet as a user stylesheet in Opera 7.6. Enjoy, and let's help keep the web open to people who have different requirements to ourselves.

Links

This site was created by Mark "Tarquin" Wilton-Jones.
Don't click this link unless you want to be banned from our site.