Articles

Accessible Cross Reference Tables

Cross-reference tables are a great tool to visually illustrate information quickly, and they're very easy to understand - if you can see them. I wanted to create such a table that was accessible on as many levels as possible, while still retaining the same look.

Thankfully, there have been many accessibility advances in traditional HTML tables that we can use for just such a task, and the particular tool I decided to use for this was the headers attribute of the <td> and <th> tags.

Consider a typical cross-reference table where you're listing your preference for several TV shows:

GreatIt's okAwful
Fireflyx
Game of Thronesx
Vikingsx
The Only Way is Essexx

Visually, this is readable and simple, but imagine this going through a screen reader. There's no correlation between the headings and row data, and the 'x' has no symantic meaning. In other words, it's not accessible.

The first step to making it better is to give the top row of heading cells an id each:

<tr>
    <td></td>
    <th id="tv_great">Great</th>
    <th id="tv_ok">It's ok</th>
    <th id="tv_awful">Awful</th>
</tr>

The W3 gives an example of how this could be used at http://www.w3.org/TR/WCAG20-TECHS/H43.html, which associates every cell with a heading. We don't want that, as most of the cells will contain no data. As such, each row pertaining to a show will look like this:

<tr>
    <th>Firefly</th>
    <td headers="tv_great">x</td>
    <td></td>
    <td></td>
</tr>

Now we have a proper relationship between data cells and their headers.

The next step in the process is to resolve that ambiguous 'x' used in the cells. Symantically, it has no meaning, and something better would be the word 'yes':

<tr>
    <th>Firefly</th>
    <td headers="tv_great">yes</td>
    <td></td>
    <td></td>
</tr>

However, now that's made our table look strange, and not aesthetically appealing:

GreatIt's okAwful
Fireflyyes
Game of Thronesyes
Vikingsyes
The Only Way is Essexyes

It's a simple matter of some CSS though to bring the table back to something that works better visually:

table.cross_ref td[headers]
{
    text-margin: -999em;
    background-image: url(tick.png);
    background-repeat: no-repeat;
    background-size: auto 100%;
    background-position: center;
}

Making our final table look like this:

GreatIt's okAwful
Firefly yes
Game of Thrones yes
Vikings yes
The Only Way is Essex yes