Main Page Content
Building Accessible Tables
CSS and
XHTML have given tables a pretty rough ride in recent times. Of course, this is the fault of just about all web developers who have at some point in their career used them for laying out page elements. This article is not about using tables for layout. It is about how to use tables to display information in an accessible manner. Use XHTML and CSS all you want for layout, but at the end of the day (if there is one on the internet) so long as there are informational relationships there will be tables. In fact, to attempt to display any of complex information relationships without a table is a mistake. If you have information to display, use tables and use them well.Table Basics
If I create a plan of what I intended to achieve yesterday and place it in a table, to a sighted
user it can be a great aid:Time | Planned Task | Preferred Task | What I actually did |
---|---|---|---|
10 - 12 | Catch up on replying to my emails. | Have a lie in. | Surfed aimlessly. |
12-1 | Have Lunch. | Have Lunch. | Had Breakfast. |
1-5 | Finish that project. | Go to video store. | Caught up on my emails. |
Blind and other severely vision impaired users rely on assistive technologies
to render web content. All text can be fed through a screen reader or refreshable braille display to be presented to the user. However, despite containing text, the table above could make a real mess of things without a few extra behind the scenes accessibility enhancements. To an assistive browser our table could well look like this:Time Planned Task Preferred Task What I actually did
10 - 12 Catch up on replying to my emails. Have a lie in. Surfed aimlessly.
12-1 Have Lunch. Have Lunch. Had Breakfast.
1-5 Finish that project. Go to video store. Caught up on my emails.
Ok, we can still kind of make a little sense of it. That is because we can see it. A blind
user can't easily scan back up and check what the third piece of information relates to. Was it what I actually did, or what I would have preferred to do? This is why we need to create relationships within the code of our table. Thankfully, from HTML4.0 a bucketful of accessibility enhancements were introduced to enable the conscientious developer to do this.Before we see how this is done let's go back to first grade. A table is created
with a table element. Everything in the table is contained between<table></table>
. Beneath this we can place rows with the <tr></tr>
element. Each row can have any number of cells using the <td></td>
. Rows can alternatively contain the header element, <th></th>
, which we will see are basically fancy cells with allow us to add turbo-charged accessibility to our table.Phew, you are still here.
Explaining Our Table
The first thing we should include in any table is a caption and a summary.
The caption will be visible to all users, the summary is a bit of hidden code for special browsers. The caption comes right under the opening table tag: <table><caption>Today's action plan: </caption>...
It should provide the user with a succinct and straight to the point description
of the table's content. The caption will be rendered on the screen when your document is accessed so keep it simple but coherent.The summary is a place to guide non-visual agents and is an attribute taken
by the opening table tag. Here you can describe the table in a bit more detail especially with regards to structure:<table summary ="This table charts my activities for the day
Our table makes much more sense now to a blind user. Actually, she can probably
figure out what it should look like. Many visually impaired users actually prefer to be labeled "vision impaired". Just because they can't see, it doesn't mean they can't visualize! Another point to keep in mind is that the summary attribute is not rendered on screen, so we can have the time of our life with it. We just need to make sure that what we write in there is relevant and provides assistance. Don't write all of the table data in there, just describe the relationship of data in the table.Relationship advice.
Now we know what our table is about, we need to show the browser how information
is related. This will help us overcome the problem of of information being rendered in continuous and seemingly unstructured lines. This is where we go to work with our table headers. The table above has 4 cells (or columns) per row, so we will need to add 4 headers to show what these columns represent. The best place for headers is in our first row, right below the <caption></caption> element:Here is what it looks like for the table above:
<tr> <th id="h1">Time.</th> <th id="h2">Planned Task</th> <th id="h3">Preferred Task.</th> <th id="h4">What I actually did.</th></tr>
Notice that each <td> tag has taken an attribute called id which has
a unique identifier. I will show you now how we use these unique identifiers to create relationships for the information in our table, and what the outcome is. We now need to link all of our columns containing the data to their appropriate header. Look how easy this is by looking at the first row of data from the table above:<tr> <td headers="h1">10 - 12</td> <td headers="h2">Catch up on replying to my emails.</td> <td headers="h3">Have a lie in.</td> <td headers="h4">Surfed aimlessly.</td></tr>What we have done here is created a link between a piece of information and its header by incorporating a headers attribute into each cell that refers to the relevant id we created in our
<th>
id attribute. All we need to do is make sure we include the same references in every row we create in our table. So its not even difficult to achieve with dynamic output from a scripted page such as one produced with asp or php. But what does all that extra stuff do. The best way to explain is to show you how a screen reader would deal with that information. Here is the output for our example row as seen by a screen reader:Time: 10 -12
Preferred Task: Have a lie in.
What I actually did: Surfed aimlessly.
...and so on for every row of data we have. To a sighted user, it may seem
a drag that every piece of data is proceeded by its header. To a blind or vision impaired user it can be the only way to keep track of a relationships in a complex set of data. If your headers are made up of quite long information, this can be quite a nuisance, but there is also a way to deal with this. Your headers can also take on an abbr attribute where you type in an abbreviated reference to your header title. here is an example using our table's headers:<tr> <th id="h1">Time.</th> <th id="h2" abbr="planned">Planned Task</th> <th id="h3" abbr="preferred">Preferred Task.</th> <th id="h4" abbr="actual">What I actually did.</th></tr>
The cool thing about this is that on its first pass, the reader will render
the full header, then for every subsequent row of data it will only read out the abbreviated value for the header. This gives the user a reference point without having to listen to the full header at every cell.Digging Deeper
Before I close up here,I will mention that HTML4.0
also introduced an axis attribute which is still to gain support amongst many assistive technologies. The axis attribute is to help explain more complex informational structures and if you want to take a look into it you will see that it is well outside the scope of this article.On close inspection the axis attribute also looks suitable for more complex data mining as well as accessibility - once the technology is in place. For more information about the axis attribute read the w3 recommendations for tables. In the meantime I hope you find these simple techniques for making your tables accessible of use and start implementing them into your own sites.