Cell headers
Silktide checks table cells that name their headings using the headers attribute, and verifies that every ID they reference actually exists. A reference to a missing ID silently breaks the connection between a cell and its heading.
In complex tables, each data cell can carry a headers attribute listing the
id values of the heading cells that apply to it. If an ID is mistyped, or
the heading it pointed to was renamed or removed, the association quietly
stops working.
<!-- Problem: no element with id="prise" exists (typo for "price") -->
<td headers="prise">$40</td>
Why this matters
A uses headers
associations to announce the right headings before each value, which is how
someone who cannot see the table keeps track of what each number means. When
a reference points at nothing, the cell is announced without its context, and
the listener has no way of knowing that anything is missing - the table
simply becomes harder or impossible to follow.
Broken references usually creep in over time: a heading's id gets renamed,
a column is deleted, or a regenerates IDs. Nothing changes visually, so
without automated checking nobody notices.
How to fix it
- Find the cell's
headersattribute and compare each listed ID against theidattributes of the table's heading cells. - Correct any typos, or update the list to the heading's current
id. - If a referenced heading no longer exists, remove the stale ID from the list.
- If the table is simple - one row or column of headings - consider dropping
headersassociations entirely and using<th>cells withscopeattributes instead, which cannot break this way.
<!-- Fixed: the reference matches a real heading -->
<th id="price">Price</th>
...
<td headers="price">$40</td>
How Silktide tests this
- Find every table cell with a
headersattribute on each page. - Split the attribute value into individual IDs.
- Look up each ID anywhere in the page.
- Report each cell that references at least one ID that does not exist.
Troubleshooting
The ID exists but the cell is still reported
Check for exact-match issues: IDs are case-sensitive, so Price and price
are different IDs. Also confirm the list is separated by spaces only - commas
or other punctuation become part of the ID and break the lookup.