Skip to main content
HTML Validation

An element with “role=rowgroup” must be contained in, or owned by, an element with the “role” value “treegrid”, “grid”, or “table”.

About This HTML Issue

An element with role="rowgroup" needs an ancestor with role="table", role="grid", or role="treegrid", or one of those elements has to claim it through aria-owns.

A rowgroup groups the rows of a table, the way <thead>, <tbody> and <tfoot> do in a native <table>. It only means something inside the structure it divides. With no table, grid or treegrid above it, a screen reader has no table to announce, so it can't report the number of rows and columns or let people move from cell to cell with its table commands.

This often shows up in cards or comparison layouts built from <div> elements. The rows and cells inside carry ARIA roles, but the outer container has only a class for styling. Add role="table" to that container and give it a name with aria-label or aria-labelledby, so screen readers can say which table it is. Pick grid or treegrid only when the widget lets people move between cells with the arrow keys.

The table doesn't have to be the rowgroup's direct parent. The validator accepts plain wrapper elements in between, as long as some ancestor has one of the three roles. When the rowgroup can't sit inside the table in the DOM, give it an id and list that id in aria-owns on the table.

If the content isn't really tabular, such as a short list of features in a card, remove role="rowgroup", role="row" and role="cell" together and use a list or plain text. If you remove only the rowgroup role, the validator reports each row instead. For real tabular data, a native <table> with <tbody>, <tr> and <td> gives you the same structure without any ARIA.

Invalid example

The rows sit in a rowgroup, but the wrapper around it has no table role.

<h2 id="specs-title">Technical details</h2>
<div class="specs">
  <div role="rowgroup">
    <div role="row">
      <span role="cell">Weight</span>
      <span role="cell">1.2 kg</span>
    </div>
    <div role="row">
      <span role="cell">Battery life</span>
      <span role="cell">18 hours</span>
    </div>
  </div>
</div>

Valid example

With role="table" and a name on the wrapper, the rowgroup has a table to belong to.

<h2 id="specs-title">Technical details</h2>
<div class="specs" role="table" aria-labelledby="specs-title">
  <div role="rowgroup">
    <div role="row">
      <span role="cell">Weight</span>
      <span role="cell">1.2 kg</span>
    </div>
    <div role="row">
      <span role="cell">Battery life</span>
      <span role="cell">18 hours</span>
    </div>
  </div>
</div>

Find issues like this automatically

Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.

Help us improve our guides

Was this guide helpful?
🌍 Trusted by teams worldwide

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.

Scheduled Reports
API Access
Open Source Standards
€5 / week

1K Weekly

1,000 monthly checks. Cancel anytime.

Get 1K Weekly →

Join teams across 40+ countries