I'm trying to create a semantically correct and accessible (WCAG 2.0) HTML5 data table. The first column contains data which also functions as a header for the row.
In HTML 4.01 / XHTML 1.0 I used to markup these cells as td
with a scope
attribute:
<td scope="row">
In HTML5 the scope
attribute is no longer allowed on the td
element. What would be the best approach for semantics and accessibility?
th
(the data aspect is lost?)td
and loose the header aspectI'm afraid that in the second scenario the table will be less accessible.
This situation got me thinking about data tables in general: in which situation would you use ONLY column headers? Because the nature of a data table implies a relationship between the data in the cells in a row. For accessibility, shouldn't the rows always get a header as well, to convey that relationship?
For example this table:
Principle | Corresponding guidelines
------------------------------------------------------------------------
Never leave a child unattended | 1, 3, 8
Always communicate what you are going to do | 4, 5, 6
Calm down before you take action | 5,9,13
Would you consider the cells in the first column (the principles) to be headers for the second column, or data cells? In other words: in what way would you markup this table?
Just because a cell is a TH, does not mean it is not also data. You should use TH with scope="row". In HTML4, you could place a scope attribute on a TD cell, in HTML5 it is no longer acceptable to have a scope attribute an a TD cell.
<table>
<thead>
<tr>
<th scope="col">Principle</th>
<th scope="col">Corresponding Guidelines</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Never leave a child unattended</th>
<td>...</td>
</tr>
</tbody>
</table>
In general most data tables have a cell that could be considered a header cell. I have seen exceptions to that rule - in particular for automatically generated data (like for example log file data) where every element in the row is of equal importance and nothing can really be considered a header.
In these instances, you could decide to dynamically set the header based on the sorting criteria but this is difficult to get to work across assistive technologies. If you were to do that, you would want to use ARIA grid markup with aria-labelledby to point to the headers. You should probably also test that solution for usability.