It may be that the web is moving rapidly, or simply my inability to read documentation. But still, after many years in this field I still find out new things about something as simple as the html table.
To make a table accessible you might think it's all about using the correct semantic markup with
<table> <tr> <th>Column 1 header</th> <th>Column 2 header</th> </tr> <tr> <td>Row 1 Column 1</td> <td>Row 1 Column 2</td> </tr> </table>
That will work, but only for really simple tables. If you do wcag validations on websites you'll soon run into the "complex tables". I haven't really found any clear definition about when a table is considered "complex". But even pretty simple tables are often regarded as complex.
So what then? What to do with a complex table?
What you need to do is use the
headers attribute for
td (and sometimes
th). The headers attribute shall contain the id of the associated table header (or header:s).
This way a readspeaker can make the connection between cells and headers. It is also important to provide a caption (or 'aria-describedby', 'title', 'summary') to provide a full description for the table.
Here is the same example with
headers attributes added, as well as a caption:
<table> <caption>Demonstration of associating headers and cells in a table</caption> <tr> <th id="header1">Column 1 header</th> <th id="header2">Column 2 header</th> </tr> <tr> <td headers="header1">Row 1 Column 1</td> <td headers="header2">Row 1 Column 2</td> </tr> </table>
Most often the hardest part isn't to create the table markup, but to test if the id/headers connection came out correctly.
For this I have created a simple script which highlights the headers connected to a certain cell when it's hovered.
In this codepen you'll also see an example of a bit more complex table: