HTML Guides for rowgroup
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.
The rowgroup role represents a group of rows within a tabular structure — similar to what <thead>, <tbody>, or <tfoot> provide in a native HTML <table>. According to the ARIA specification, the rowgroup role should be used on elements that serve as structural containers for rows within a grid, table, or treegrid. A <header> element is not appropriate for this role because it carries its own strong semantic meaning (typically banner or a sectioning header), and overriding it with role="rowgroup" creates a conflict that the W3C validator flags.
This matters for several reasons. First, assistive technologies rely on correct role assignments to convey the structure of a page. When a <header> element is given role="rowgroup", screen readers receive contradictory signals about what the element represents, which can confuse users. Second, the HTML specification restricts which ARIA roles can be applied to certain elements — the <header> element does not allow rowgroup as a valid role override.
To fix this issue, you have two main options:
- Replace the <header> element with a <div> — since <div> has no implicit ARIA role, it freely accepts role="rowgroup".
- Use native HTML table elements — replace the custom ARIA table structure with <table>, <thead>, <tbody>, <tr>, <th>, and <td>, which provide the correct semantics without requiring any ARIA roles.
Examples
❌ Incorrect: role="rowgroup" on a <header> element
<div role="table" aria-label="Quarterly Sales">
<header role="rowgroup">
<div role="row">
<span role="columnheader">Quarter</span>
<span role="columnheader">Revenue</span>
</div>
</header>
<div role="rowgroup">
<div role="row">
<span role="cell">Q1</span>
<span role="cell">$1.2M</span>
</div>
</div>
</div>
The validator reports Bad value “rowgroup” for attribute “role” on element “header” because <header> cannot accept the rowgroup role.
✅ Fix option 1: Use a <div> instead of <header>
<div role="table" aria-label="Quarterly Sales">
<div role="rowgroup">
<div role="row">
<span role="columnheader">Quarter</span>
<span role="columnheader">Revenue</span>
</div>
</div>
<div role="rowgroup">
<div role="row">
<span role="cell">Q1</span>
<span role="cell">$1.2M</span>
</div>
</div>
</div>
A <div> is semantically neutral, so role="rowgroup" is perfectly valid on it.
✅ Fix option 2: Use native HTML table elements
<table>
<caption>Quarterly Sales</caption>
<thead>
<tr>
<th>Quarter</th>
<th>Revenue</th>
</tr>
</thead>
<tbody>
<tr>
<td>Q1</td>
<td>$1.2M</td>
</tr>
</tbody>
</table>
Native table elements like <thead> and <tbody> implicitly carry the rowgroup role, so no ARIA attributes are needed at all. This approach is generally preferred because it provides the best accessibility support out of the box and results in cleaner, more maintainable markup. Only use ARIA table roles when you cannot use native HTML tables (for example, when building a custom grid layout that requires non-table CSS).
Ready to validate your sites?
Start your free trial today.