Table caption and summary cannot match
Last updated:
Related Guides
Table caption and summary must not be identical
The table caption is a concise title and must not be duplicated by a summary or structural description.
This issue appears in data tables when authors repeat the same text in multiple places.
It affects screen reader users who depend on clear, non-redundant announcements to understand the table.
Why It Matters
Redundant announcements slow down navigation and make it harder to parse content. When the caption and any descriptive text say the same thing, screen reader users hear the title twice without gaining context.
Cognitive load increases when users must sift through repeated information to find what matters: how the table is organized and how to read it.
Clear, distinct labeling supports users with vision and cognitive disabilities and aligns with WCAG goals for meaningful structure and labels.
Common Causes
- Copying the caption text into a summary or description field.
- Assuming more places with the same text improves SEO or accessibility.
- Using outdated patterns that rely on the summary attribute without adding structural details.
- Auto-generated tables that mirror the caption into a hidden field.
- Lack of a real structural description for complex tables.
How to Fix
- Prefer modern patterns over the summary attribute:
- Do not add summary in new code (it is obsolete in HTML).
- If legacy tables include summary, keep it only if it adds structural guidance and does not repeat the caption. Otherwise remove it.
- Provide a brief, visible title:
- Use the caption element for a short, descriptive title (one concise sentence).
- Offer structural description when needed:
- For simple tables, the caption is often enough.
- For complex tables, add a nearby text description (before the table) that explains layout, groups, or special reading order.
- Reference that description with
aria-describedbyon the table.
- Mark up headers and associations correctly:
- Use thead/tbody/tfoot, and th with
scope="col"orscope="row"for simple tables. - For complex tables with multi-level headers, use headers/id associations.
- Use thead/tbody/tfoot, and th with
- Ensure uniqueness:
- The caption should name the table.
- The description (formerly summary) should explain how to interpret it. Avoid reusing the caption text.
Recommendation: Keep captions short (5–12 words) and descriptions focused on structure (1–3 sentences).
How to Test
Keyboard
- Navigate to the table using Tab/Shift+Tab or quick navigation keys (if supported). Ensure focus is predictable and no traps occur.
Screen reader
- With NVDA or JAWS on Windows, navigate to the table and listen: the screen reader should announce the caption once and the table dimensions. If a description is referenced, it should add structural guidance, not repeat the caption.
- With VoiceOver on macOS, use VO+Command+T (table list) or navigate linearly and listen for a distinct title and any description.
Mobile/touch
- iOS VoiceOver: swipe to the table; ensure the rotor reveals a clear title and any description is distinct.
- Android TalkBack: navigate by items and confirm there is no duplicated title text.
Code inspection
- Check for summary on table elements. If present, confirm it adds structure and is not identical to the caption. Prefer replacing it with
aria-describedby. - Verify proper use of caption, th scope, thead/tbody, and any headers/id associations.
Good Example
<div id="sales-structure" class="sr-only">Two columns: Region and Total. Headers in the first row. Read across rows to find each region’s total.</div>
<table aria-describedby="sales-structure">
<caption>Quarterly sales by region</caption>
<thead>
<tr>
<th scope="col">Region</th>
<th scope="col">Total</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">North</th>
<td>$120,000</td>
</tr>
<tr>
<th scope="row">South</th>
<td>$98,500</td>
</tr>
</tbody>
</table>CSS to visually hide but keep accessible:
.sr-only {
position: absolute;
width: 1px; height: 1px;
margin: -1px; padding: 0; border: 0;
clip: rect(0 0 0 0); clip-path: inset(50%);
overflow: hidden; white-space: nowrap;
}Bad Example
<table summary="Quarterly sales by region">
<caption>Quarterly sales by region</caption>
<tr>
<th>Region</th>
<th>Total</th>
</tr>
<tr>
<td>North</td>
<td>$120,000</td>
</tr>
</table>Issues:
- summary repeats the caption verbatim (no structural guidance).
- Obsolete summary attribute used in new code.
- Missing scope and sectioning (thead/tbody) for clarity.
Quick Checklist
- Caption is a concise, visible title (not a description).
- No duplicated text between caption and any description.
- Avoid summary in new code; use
aria-describedbyto link to nearby structural text when needed. - Provide structural guidance for complex tables, near the table.
- Use proper headers: thead/tbody and th with scope.
- Screen readers announce a distinct title and, if present, a distinct description.
- Remove or revise legacy summary attributes that repeat the caption.