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.