We'd like to set Google Analytics cookies to learn how people use the Knowledge Base, so we can improve it. We set them only if you accept.

Skip to main content
Digital Accessibility Knowledge Base

td-headers-attr

Web validation

All cells in a table element that use the headers attribute must only refer to other cells in the same table.

A data table has to convey clear relationships between header cells and the data they label. When a <td> uses the headers attribute, the value must reference the id of a header cell (<th>) that lives in the very same table. Otherwise, screen-reader users hear the wrong header, or none at all, and cannot work out how the data is organised. Using the attribute correctly (or, whenever possible, adding a scope attribute to each <th>) keeps table navigation predictable for everyone.

Pass Patterns

Data cells reference header cells within the same table

Each headers value matches an id that appears in a <th> inside the same table row or column, so assistive technology can announce the right pairing.

HTML
<table>
    <tr>
        <th id="name" scope="col">Name</th>
        <th id="score" scope="col">Score</th>
    </tr>
    <tr>
        <td headers="name">Alex</td>
        <td headers="score">95</td>
    </tr>
</table>

Fail Patterns

Data cell points to a header that is not in the same table

The first <td> points to external-header, an id that sits in a different table. A screen reader will not find the target header and will announce the cell with no context or fall back to the text of the <th> in the scope.

HTML
<!-- First (hidden) table that defines a header used elsewhere -->
<table hidden>
    <tr><th id="external-header">Sold out</th></tr>
</table>


<!-- Visible table with broken reference -->
<table>
    <tr>
        <th id="product" scope="col">Product</th>
        <th id="price" scope="col">Price</th>
    </tr>
    <tr>
        <td headers="external-header">Widget A</td> <!-- ❌ Wrong table -->
        <td headers="price">10.00</td>
    </tr>
</table>

WCAG techniques

Sufficient techniques

Failure techniques

Try It Yourself

Using a screen reader

New to screen reader testing, or need a refresher?
Review this article first: Practical guides for using screen readers

  1. Load the page and open a screen reader, then move focus into the data table.
  2. Navigate cell by cell with the table-navigation commands of your screen reader.
  3. Listen for the announced header before each data value.

Expected result: The header that is announced matches the visible column or row header.

Actual result: The header is missing or mismatched, so the data makes little sense, or it falls back to the table header of the column or row if it exists.

FAQ

How does this issue relate to 1.3.1 Info and Relationships?

SC 1.3.1 requires that information conveyed visually is also available programmatically. Correct references in the headers attribute expose header-data relationships in the accessibility tree, allowing assistive technology to communicate the same structure that sighted users perceive.

Why is this issue marked as Serious?

When headers are mis-mapped, screen-reader users must guess which data belongs to which header, or receive misleading information, slowing them down and increasing errors.

Standards and Regulations

StandardSuccess CriterionReference
WCAG 2.21.3.1 Info and Relationships (A)Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
EN 301 5499.1.3.1 Info and RelationshipsSame as the WCAG text.
Section 5081194.22(g)Row and column headers shall be identified for data tables.
Section 5081194.22(h)Markup shall be used to associate data cells and header cells for data tables that have two or more logical levels of row or column headers.
508 Trusted Tester1.3.1-cell-header-association, 14.BAll data cells are programmatically associated with relevant headers.

Personas impacted by this issue

Learn More