Skip to content

Structure & headings

A Table's Title Is in a Cell, Not a Caption

The table's title sits in a cell that spans every column, so screen readers treat it as data or a header, not as the table's name.

table-fake-captionWCAG 2.0Introduced in WCAG 2.0.Level AA — the minimum. Missing it blocks people outright.

Status
SeriousSerious — Significant friction, or information that is lost.Experimentalaxe-core has this rule, but runs it only when a team turns experimental rules on.
Owner
DevContentTest
Audit
Automated+ManualA scanner finds it; a person confirms the fix.

Experimental rule. Experimental in axe-core: it runs only when a team turns experimental rules on, so a clean default scan says nothing about it. WCAG 1.3.1 Info and Relationships still applies.

Save as PDF (opens in a new tab)

Why it matters

Some tables put their title in a first row that stretches across all columns. It looks like a title, but code-wise it is just another cell.

Screen readers don't announce it as the table's name when someone arrives. Worse, they may read it as a column header for every cell below, which adds noise to each cell.

Who it affects

Who it affects, and how much
WhoWhat they experienceImpact
Screen reader usersThey hear "table, 5 columns" with no name, then the title repeated as a header on every cell.High impact
Low-vision users (magnification)Affected only if they also use a screen reader, as many do.Partial impact

Business & product impact

Business & product impact, with how much each claim weighs
AreaWhyImpact
LegalIt relates to WCAG 1.3.1 at Level A. Complaints under Australia's Disability Discrimination Act point to WCAG, and EN 301 549 includes it too.Moderate impact
ConversionPrice, plan or rate tables that read badly make comparison harder, and people may leave.Moderate impact
SEOLittle or no search benefit — don't sell it as one.Low impact
Brand trustMessy tables suggest the data wasn't built with care.Low impact
Cost to fixA small markup change. Fix it in the shared table component and it's fixed everywhere.High impact

Fixing it in code

Give the table a real caption

Don't

<table>
  <tr><th colspan="3">Opening hours</th></tr>
  <tr><th>Day</th><th>Open</th><th>Close</th></tr>
  <tr><td>Monday</td><td>9am</td><td>5pm</td></tr>
</table>

A screen reader says: “Table, 3 columns, 3 rows. Opening hours, Day, Monday…”

Do

<table>
  <caption>Opening hours</caption>
  <tr><th>Day</th><th>Open</th><th>Close</th></tr>
  <tr><td>Monday</td><td>9am</td><td>5pm</td></tr>
</table>

A screen reader says: “Opening hours, table, 3 columns, 2 rows. Day, Monday…”

The <caption> element is read as the table's name, not as data.

Designer's handoff note

Give every data table a short title in your designs, and label it "caption" in the handoff.

You can style a <caption> to look just like your current title row.

Quick test

Tool

NVDA (opens in a new tab) (free on Windows)

Duration

1 min

Checklist

Pass
You hear the table's title as its name, and data cells don't repeat it.
Fail
The table has no name, or the title is read as a header with each cell.

Check these at the same time

What a green scan still misses

This rule is experimental, so many scans skip it. It also can't tell if a table needs a title at all, or if the title is clear.

Reference

Status
ExperimentalExperimental in axe-core: it runs only when a team turns experimental rules on, so a clean default scan says nothing about it. WCAG 1.3.1 Info and Relationships still applies.
Rule ID
table-fake-caption
Raised by
  • axe-core: “Data or header cells must not be used to give caption to a data table.”
WCAG
Other standards
EN 301 549 9.1.3.1 · RGAA 5.4.1
Last reviewed
16 October 2026