HTML Guides for rowheader
Learn how to identify and fix common HTML validation errors flagged by the W3C Validator — so your pages are standards-compliant and render correctly across every browser. Also check our Accessibility Guides.
A <th> at the start of a data row already has the implicit role rowheader, so adding role="rowheader" to it changes nothing for screen readers.
The browser gives each <th> its ARIA role based on where the cell sits in the table. Header cells in the <thead>, or in a top row of headers, become columnheader. A header cell followed by <td> cells in the same row becomes rowheader. Add scope="row" when you want to state the direction outright: it marks the cell as the header for the rest of its row. The role attribute repeats information the table structure already carries and only makes the markup longer.
You'll get this warning for role="rowheader" on every <th>, whatever its position. If the cell actually heads a column, for example a <th> inside <thead>, the role is also incorrect: it replaces columnheader, so screen readers announce the cell as the label of a row.
Expect an error alongside the warning in most tables. A <th> can't carry any role attribute when its <table> has no role of its own, or has role="table", role="grid" or role="treegrid". Deleting role="rowheader" clears the warning and the error together.
Table plugins and page builders tend to put a role on every row and cell. The rowheader role is for tables built from generic elements such as <div> or <span>, which have no native way to mark a cell as a row header. On a <th>, remove the attribute and keep scope="row". If the same table also sets roles on its <tr>, <td> or <tbody> elements, the validator flags those too, so remove them in the same change.
Invalid example
<table>
<thead>
<tr>
<th scope="col">Plan</th>
<th scope="col">Monthly price</th>
<th scope="col">Storage</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row" role="rowheader">Basic</th>
<td>$5</td>
<td>10 GB</td>
</tr>
<tr>
<th scope="row" role="rowheader">Team</th>
<td>$20</td>
<td>100 GB</td>
</tr>
</tbody>
</table>
Valid example
<table>
<thead>
<tr>
<th scope="col">Plan</th>
<th scope="col">Monthly price</th>
<th scope="col">Storage</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Basic</th>
<td>$5</td>
<td>10 GB</td>
</tr>
<tr>
<th scope="row">Team</th>
<td>$20</td>
<td>100 GB</td>
</tr>
</tbody>
</table>
Validate at scale.
Ship accessible websites, faster.
Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.
1K Weekly
1,000 monthly checks. Cancel anytime.
Get 1K Weekly →Join teams across 40+ countries