table-headers-attr-valid

Table cell "headers" attribute must reference valid header cells

automaticWCAG 1.3.1 (A)confidence: highseverity: seriousperceivable

Checks that each id in a <td>/<th> headers attribute resolves to a cell (<td> or <th>) within the same table (not missing, not a non-cell element, not itself).

Applies to. Applies to <td>/<th> elements that carry a non-empty headers attribute, within a <table> whose semantic role is still table/grid/treegrid -- an explicit role of anything else (role="presentation"/"none", but also role="heading" or any other real role) replaces the native table semantics, leaving no table for headers to describe. A presentational role on a table with a global ARIA attribute or a tabindex is ignored, as WAI-ARIA's conflict resolution has it, and the table stays one. Matches ACT a25f45's applicability.

Expectation. Every id token in the headers attribute resolves to an element that: (a) exists, (b) is a cell (<td> or <th>) of the same <table> as the referencing cell, and (c) is not the cell itself. A <td> serving as a header via role="columnheader"/"rowheader" is a valid target, same as a plain <th> -- ACT a25f45 does not require the native tag.

What a finding reports.

  • invalid: one item per id in the headers attribute that does not point at a valid header: id, and reason, which is missing (no element has that id), self-reference (the cell points at itself), not-a-cell (the element is not a <td> or <th>) or different-table (the cell is in another table).

These data.details fields help to read and reproduce a finding. Apart from reasonCode and the few fields Output schema names as stable, they are not a stable contract: a field may be renamed or dropped in a minor release, so don’t build on them.

Examples

pass
<table>
<tr><th id="h1">Name</th></tr>
<tr><td headers="h1">Apple</td></tr>
</table>

headers="h1" resolves to a real cell in the same table.

fail
<table>
<tr><th id="h2">Name</th></tr>
<tr><td headers="missing">Banana</td></tr>
</table>

headers references an id that doesn't exist in the table.

View source