Accessibility
a11y/table-headers
Data tables mark their header cells with th (with scope when needed); layout tables carry role="presentation".
seriousstaticWCAG 1.3.1 · Afe-a11y-tables
Why
Screen readers read a cell together with its column and row headers ("Price, Basic: Free"). With bold <td> cells instead of <th>, a table of numbers becomes a list of values with no meaning.
Fix
Use <th scope="col"> for column headers (in <thead>) and <th scope="row"> for the first cell of each row when it names the row. Add a <caption>. For tables used only to lay out an email or a legacy page, set role="presentation".
Examples
<!-- bad -->
<table><tr><td><b>Plan</b></td><td><b>Price</b></td></tr><tr><td>Basic</td><td>Free</td></tr></table>
<!-- good -->
<table>
<caption>Plans</caption>
<thead><tr><th scope="col">Plan</th><th scope="col">Price</th></tr></thead>
<tbody><tr><th scope="row">Basic</th><td>Free</td></tr></tbody>
</table>Sources
Facts
- Id
a11y/table-headers- Severity
- serious
- Check
- static checked in the source by
audit - Applies to
htmlangularvuesvelteastrojsx- WCAG 2.2
- 1.3.1, level A
- Same problem in
- axe-core
td-has-header, axe-coreth-has-data-cells - Taught by the skill
fe-a11y-tablesData tables- Since version
- 0.1.0
Read it in the terminal
npx github:dawidolko/frontend-skills explain a11y/table-headers