Skip to main content
WCAGrules
Quick navigation

Do not mis-wire headers and id attributes in tables

A data cell points at its header by id, and points at the wrong one, or at an id that is not in the table any more. F90 is the failure technique covering that, so a match is a defect rather than a technique. The usual cause is maintenance rather than design. Somebody duplicated a row, the ids came along with it, and nobody went back to update them. Two shapes come out of that. A reference to an id that does not exist, which any validator finds, and a reference to a real header describing a different column, which nothing but a person will ever find. Often the wiring is the mistake in itself. Headers and ids exist for tables with more than one level of heading, so a simple table wants scope, and reaching for headers and id on one is how this failure gets built.

How we find it in an audit

Broken references flag instantly, because a headers value pointing at an id nowhere in the table is a mechanical check. The valid-but-wrong case needs a reviewer, who reads each data cell alongside the header it claims and asks whether that pairing is true. Grade tables and pricing grids get the most time, since repeated sub-headings like 1, 2 and Final read identically under two different parents and a swap between them changes nothing on the screen. We flag tables using headers and id where scope would do as well, because that setup is what this failure needs to exist.

How affected users experience it

Table navigation in a screen reader means hearing the header announced as you move, which is the entire reason the wiring exists. When the wiring is wrong, the announcement stays confident and becomes false. A score gets read out under Exams when it belongs under Projects, and nothing signals that anything went wrong. That is worse than silence. Silence at least tells a user to go and check something.

Passes vs. fails

Passes: headings exist in the code. Fails: one flat wall of text.

Passes

<th id="q3">Q3</th> ...
<td headers="q3">$40,000</td>
<!-- on a single-level table, drop headers and id and put scope="col" on the th -->

Fails

<th id="q3">Q3</th> ...
<td headers="q4">$40,000</td> <!-- no cell in this table has id="q4" -->

How this gets tested

The W3C publishes test rules that define what a checker looks for here.

The other techniques filed under this rule

52 guides on this site are filed under 1.3.1 Info and Relationships. W3C documents this one as a failure of that rule, so it describes a way the rule gets broken rather than a way to pass it.

This guide is our interpretation of W3C technique F90: Failure of Success Criterion 1.3.1 for incorrectly associating table headers and content via the headers and id attributes. W3C publishes its techniques as guidance rather than as the standard, and says so on every one of them. The success criterion is what conformance is measured against, and a technique is one documented way to meet it.

Go somewhere useful

Find tools, resources and your workspace.

29 destinations