Structure & headings
A Table Header Cell Has No Text
When a table header is blank, screen reader users moving through that column hear no label, so they must guess what each value means.
empty-table-headerBest practiceBest practice — not a WCAG requirement, but it helps people all the same.
- Status
- MinorMinor — Cosmetic, or best practice.CurrentScanners run this rule today.
- Owner
- DesignDevContentTest
- Audit
- Automated+ManualA scanner finds it; a person confirms the fix.
Why it matters
Screen readers read the column or row header as people move between cells. That's how they know a cell says "$40" for price, not for shipping.
A blank header gives them nothing. They lose track of the table and may have to read it again from the top.
Who it affects
| Who | What they experience | Impact |
|---|---|---|
| Screen reader users | They move into a column and hear only the cell value, with no label to explain it. | High impact |
| Low-vision users (magnification) | Affected only if they also use a screen reader, as many do. | Partial impact |
| Cognitive and neurodivergent users | An unlabelled column, often of icons or buttons, is harder to understand at a glance. | Partial impact |
| Voice control users | Mostly unaffected, though a visible header helps them name what they want. | Partial impact |
Business & product impact
| Area | Why | Impact |
|---|---|---|
| Legal | This is a best practice, not a WCAG 2.2 failure on its own. Still, unclear tables can feed into complaints under Australia's Disability Discrimination Act. | Low impact |
| Conversion | In price, plan or order tables, an unlabelled column can lead to wrong choices or abandoned tasks. | Moderate impact |
| SEO | No real search benefit — don't sell it as one. | Low impact |
| Brand trust | Data tables that make sense to everyone show care for detail. | Low impact |
| Cost to fix | Usually a few words of hidden text or a tag swap. Fix it once in the shared table component. | High impact |
Fixing it in code
A column of action buttons
Don't
<th></th>
<!-- each row: -->
<td><button>Edit</button></td>A screen reader says: “Edit, button”
Do
<th><span class="visually-hidden">Actions</span></th>
<!-- each row: -->
<td><button>Edit</button></td>A screen reader says: “Actions, Edit, button”
The header now has text a screen reader can read, while staying visually empty.
The empty top-left corner cell
Don't
<tr>
<th></th>
<th scope="col">Basic</th>
<th scope="col">Pro</th>
</tr>A screen reader says: “Blank, then the corner cell is read as a header with nothing in it”
Do
<tr>
<td></td>
<th scope="col">Basic</th>
<th scope="col">Pro</th>
</tr>A screen reader says: “Basic, column header; Pro, column header”
A cell that labels nothing shouldn't be a header, so make it a normal cell.
Designer's handoff note
Give every table column a short title, even icon or button columns. If it must look empty, note the hidden label in your spec — for example, "Actions".
Quick test
Tool
NVDA (opens in a new tab) (free on Windows)
Checklist
- Pass
- Every column you move into is announced with a clear header name.
- Fail
- Some column gives you only the cell value, with no header name.
What a green scan still misses
A scanner finds blank headers. It can't tell whether a header's words actually describe the column, or whether a cell should be a header at all.
Reference
- Rule ID
empty-table-header- Raised by
- axe-core: “Table header text should not be empty”
- WCAG
- Best practice — not a WCAG requirement
- Last reviewed
- 14 October 2026