HTML Guides for grid
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.
An element with role="row" must sit inside an element whose role is table, grid, treegrid, or rowgroup, or be claimed by one through aria-owns. A row on its own has no structure to belong to, so assistive technologies cannot tell which table or grid it is part of.
The row role describes one row of a composite structure. Those four allowed owners fall into two groups: table and rowgroup for static tabular data, and grid and treegrid for interactive widgets that support keyboard navigation. In every case the container supplies the context a screen reader needs to announce the row's position and its cells. Placed outside such a container, the row is orphaned and the whole table semantics break down.
The most reliable fix is to nest the role="row" element inside its container in the DOM. When your layout prevents that, keep the row where it is and point aria-owns from the container at the row's id.
Invalid example
The role="row" is a sibling of the table, so nothing contains or owns it:
<div role="table" aria-label="Prices"></div>
<div role="row">
<span role="cell">Basic</span>
<span role="cell">$9</span>
</div>
Valid example
Nest the row inside the element with role="table":
<div role="table" aria-label="Prices">
<div role="row">
<span role="cell">Basic</span>
<span role="cell">$9</span>
</div>
</div>
If the DOM nesting is not possible, leave the row in place and add aria-owns="price-row" to the container so assistive technologies still treat it as the owner.
A <tr> element already has an implicit ARIA role of row, so adding role="row" is redundant when the parent <table> uses its default semantics or has a role of table, grid, or treegrid.
HTML tables come with built-in accessibility semantics. The <table> element implicitly has role="table", and <tr> implicitly has role="row". Browsers and assistive technologies already understand this structure, so explicitly adding these roles is unnecessary and flagged by the W3C validator.
The only time you'd need to add a role to a <tr> is when the table's native semantics have been overridden — for example, if the <table> has been repurposed with a non-table role like role="presentation" or role="none". In that case, you'd need explicit ARIA roles to restore row semantics.
Incorrect Example
<table>
<tr role="row">
<th>Name</th>
<th>Email</th>
</tr>
<tr role="row">
<td>Alice</td>
<td>alice@example.com</td>
</tr>
</table>
Fixed Example
Simply remove the redundant role="row" from the <tr> elements:
<table>
<tr>
<th>Name</th>
<th>Email</th>
</tr>
<tr>
<td>Alice</td>
<td>alice@example.com</td>
</tr>
</table>
The same fix applies if your <table> explicitly has role="table", role="grid", or role="treegrid" — the <tr> elements still don't need an explicit role="row" because the browser infers it automatically.
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.
Pro Trial
Full Pro access. Cancel anytime.
Start Pro Trial →Join teams across 40+ countries