About This HTML Issue
The HTML specification requires that every row in a table has at least one cell that starts on that row. A “cell beginning on a row” means a <td> or <th> element that is directly placed in that <tr>, as opposed to a cell that merely spans into it via rowspan from an earlier row. When the validator encounters a row with no cells beginning on it, it flags the error because the row is structurally meaningless — it contributes nothing to the table’s data model.
This issue commonly arises in two scenarios:
-
Empty
<tr>elements — A<tr>that contains no<td>or<th>children at all. This sometimes appears when developers use empty rows for visual spacing, or when content management systems generate leftover markup. -
Rows fully covered by
rowspan— When cells in preceding rows userowspanvalues large enough to span over an entire subsequent row, that subsequent row ends up with no cells beginning on it, even if it technically “has” cells passing through it.
This matters for several reasons. Screen readers and other assistive technologies rely on a well-formed table structure to navigate cells and announce their content. An empty or fully-spanned row confuses this navigation. Browsers may also handle malformed tables inconsistently, leading to unexpected rendering. Ensuring every row has at least one cell that begins on it keeps your tables semantically correct and accessible.
How to fix it
-
Remove empty rows. If a
<tr>has no cells and serves no purpose, delete it entirely. -
Add cells to the row. If the row is intentional, populate it with
<td>or<th>elements (they can be empty if needed). -
Adjust
rowspanvalues. If previous cells span too many rows, reduce theirrowspanso that every row still has at least one cell of its own. -
Use CSS for spacing. If empty rows were used for visual spacing, use CSS
margin,padding, orborder-spacinginstead.
Note that self-closing <tr /> elements are treated the same as <tr></tr> — they produce an empty row and will trigger this error.
Examples
Empty row in <tbody> (incorrect)
<table>
<tbody>
<tr>
</tr>
<tr>
<td>Data</td>
</tr>
</tbody>
</table>
The first <tr> has no cells, so the validator reports that row 1 of the <tbody> row group has no cells beginning on it.
Empty row removed (correct)
<table>
<tbody>
<tr>
<td>Data</td>
</tr>
</tbody>
</table>
Row fully covered by rowspan (incorrect)
<table>
<tbody>
<tr>
<td rowspan="3">Spans three rows</td>
<td rowspan="3">Also spans three</td>
</tr>
<tr>
</tr>
<tr>
</tr>
</tbody>
</table>
Rows 2 and 3 have no cells beginning on them — all cells originate from row 1. Even though cells pass through those rows via rowspan, the validator still requires at least one cell to begin on each row.
Corrected rowspan with cells on every row (correct)
<table>
<tbody>
<tr>
<td rowspan="3">Spans three rows</td>
<td>Row 1 detail</td>
</tr>
<tr>
<td>Row 2 detail</td>
</tr>
<tr>
<td>Row 3 detail</td>
</tr>
</tbody>
</table>
Each row now has at least one <td> that begins on it, satisfying the requirement.
Using CSS instead of empty rows for spacing (correct)
<table>
<tbody>
<tr>
<td>First item</td>
</tr>
<tr style="height: 1.5em;">
<td>Second item with extra space above</td>
</tr>
</tbody>
</table>
Instead of inserting an empty row for spacing, apply CSS to the row or cells that need additional space.
Find issues like this automatically
Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.