Ashley Sheridan​.co.uk

Accessible Cross Reference Tables

Posted on

This article was originally posted on the TMW Tech Blog on the 30th of Jan 2015 but I've amended the prose slightly here

I've recently rebuilt this website, mainly in order to move it off of the old CodeIgniter framework to Laravel, and take advantage of the modern features of PHP. The rebuild has given me a great opportunity to go through a lot of the content on the site and re-write it, and one area I focused on a lot was the CV, as the previous incarnation was a bit of a wall of text!

A key part of making this page more readable was to lay out my skills in a cross reference table of individual skill vs level of skill. It struck me as I built this initially that while this was much easier on the eyes, I'd actually taken a bit of a step backwards for anyone who was browsing my site non-visually. I had a look around at what options were available to me and set to work to improve it.

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 semantic 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

And there it is. Visually pleasing, and accessible.