About This Accessibility Rule
The scope attribute establishes the relationship between header cells and data cells in a data table. When a screen reader encounters a table, it uses these relationships to announce the relevant header as a user moves between cells. For example, if a column header has scope="col", the screen reader knows that all cells below it in that column are associated with that header. Similarly, scope="row" tells the screen reader that all cells to the right of that header in the same row belong to it.
When scope is used incorrectly — placed on a <td> element in HTML5, applied to a non-table element, or given an invalid value — screen readers may misinterpret the table structure. This primarily affects blind and deafblind users who rely on screen readers for table navigation, as well as users with mobility impairments who may use assistive technologies to navigate structured content. Instead of hearing meaningful header announcements as they move through cells, these users may hear nothing, or worse, hear incorrect header associations that make the data incomprehensible.
This rule is classified as a Deque best practice. Correct use of the scope attribute aligns with the broader goal of making data tables programmatically determinable, which supports WCAG 1.3.1 (Info and Relationships) — the requirement that information and relationships conveyed through presentation can be programmatically determined.
How to fix it
Follow these steps to ensure scope is used correctly:
-
Use
scopeonly on<th>elements. In HTML5, thescopeattribute is only valid on<th>elements. If you’re using HTML4, it’s also permitted on<td>, but this is uncommon and generally unnecessary. -
Use only valid values. The
scopeattribute should be set tocol(for column headers) orrow(for row headers). The valuescolgroupandrowgroupare also valid when headers span groups, butrowandcolcover the vast majority of use cases. Do not use arbitrary or misspelled values. -
Add
scopeto all<th>elements. Every<th>in your table should have ascopeattribute so screen readers can unambiguously associate headers with their data cells. -
Use
<th>for headers and<td>for data. Make sure you’re not using<td>for cells that function as headers — use<th>instead, and add the appropriatescope.
Examples
Incorrect: scope on a <td> element (invalid in HTML5)
<table>
<tr>
<td scope="col">Name</td>
<td scope="col">Score</td>
</tr>
<tr>
<td>Alice</td>
<td>95</td>
</tr>
</table>
Here, scope is placed on <td> elements instead of <th>. Screen readers won’t recognize these cells as headers.
Incorrect: invalid scope value
<table>
<tr>
<th scope="column">Name</th>
<th scope="column">Score</th>
</tr>
<tr>
<td>Alice</td>
<td>95</td>
</tr>
</table>
The value column is not valid — the correct value is col.
Incorrect: <th> elements without scope
<table>
<tr>
<th>Name</th>
<th>Score</th>
</tr>
<tr>
<th>Alice</th>
<td>95</td>
</tr>
</table>
Although <th> elements are used, none have a scope attribute. Screen readers must guess whether each header applies to a column or a row.
Correct: proper use of scope on <th> elements
<table>
<caption>Student Test Scores</caption>
<tr>
<th scope="col">Name</th>
<th scope="col">Score</th>
</tr>
<tr>
<th scope="row">Alice</th>
<td>95</td>
</tr>
<tr>
<th scope="row">Bob</th>
<td>88</td>
</tr>
</table>
Column headers use scope="col" and row headers use scope="row", all on <th> elements. A screen reader navigating to the cell containing “95” can announce “Name: Alice, Score: 95” — giving the user full context without needing to visually scan the table. The <caption> element provides an accessible name for the table, further improving the experience.
Help us improve our guides
Detect accessibility issues automatically
Rocket Validator scans thousands of pages with Axe Core and the W3C Validator, finding accessibility issues across your entire site.