How to fix an empty table header cell?
empty-table-header page
The issue
A screen reader announces a cell’s header as the user moves through a table. When the header is empty, there is nothing to announce, so a column of values or icons arrives with no label. A sighted reader may infer it from the layout; a listener can’t.
The cause is usually a header that shows only an icon, such as a checkmark column, or the empty corner cell at the top left of a table marked up as <th>.
Scope
Every visible <th> is checked. Its name comes from aria-labelledby, aria-label, its own text, or its title, in that order. A header with none of these is reported.
How to check you have it
- In probeo: the page reports
empty-table-header, “Table header cells should not be empty”, as minor. It is a best practice rule rather than a WCAG criterion. - By hand: look at each
<th>in DevTools and check it has text, or an icon with a text alternative. - With a tool: axe DevTools has a rule with the same name. The browser’s accessibility tree shows each header’s computed name.
The fix
Give every header cell a name, and make a cell that isn’t a header a <td>.
For an icon header, add text that is hidden visually but available to screen readers. For the empty corner cell of a table, use <td>, since it doesn’t label anything.
<th scope="col"><span class="visually-hidden">Included</span><svg aria-hidden="true">…</svg></th>
<td></td> <!-- the empty corner cell -->.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }Done when: every <th> has a name, and the check above comes back clean.
Do not
- Do not leave an icon as a header’s only content without a text alternative.
- Do not mark an empty corner cell as
<th>. - Do not hide the header text with
display: none; it is then removed from the accessibility tree.
FAQ
Does a title attribute count?
Yes, as a last resort. Visible or visually hidden text is better, since title isn’t announced consistently.
Are layout tables checked?
Yes. Any visible <th> is checked, so a layout table shouldn’t use <th> at all.
Why is the corner cell a problem?
Because it is marked as a header but labels nothing. Making it a <td> removes the empty header.
Which product detects this
Probeo checks this on every page of your site as part of Site Clarity. This page explains one instance; the product tells you every page that has it.