About This HTML Issue
The HTML specification defines a strict nesting hierarchy for table elements. A <td> (table data cell) must be a direct child of a <tr> (table row), and that <tr> must in turn live inside a <table>, <thead>, <tbody>, or <tfoot>. When the browser’s parser encounters a <td> in an unexpected location, it considers it a “stray” start tag — meaning the element has no valid place in the current parsing context.
This error commonly occurs in several scenarios:
-
A
<td>is placed directly inside a<table>without a wrapping<tr>. -
A
<td>is placed directly inside<thead>,<tbody>, or<tfoot>without a<tr>. -
A
<td>appears completely outside of any table structure, such as inside a<div>or the document<body>. -
A
<tr>tag was accidentally deleted or misspelled during editing, leaving its<td>children orphaned.
Why this matters
Browser inconsistency: Browsers use error-recovery algorithms to handle invalid markup, but they may handle stray table cells differently. Some browsers might silently insert an implicit <tr>, while others might move the content outside the table entirely. This leads to unpredictable rendering across browsers.
Accessibility: Screen readers and assistive technologies rely on proper table semantics to navigate and announce cell content. A stray <td> breaks the logical row-and-column relationship, making the data difficult or impossible for assistive technology users to interpret correctly.
Maintainability: Invalid nesting makes your markup harder to understand, debug, and style with CSS. Table-specific CSS selectors and properties may not behave as expected when the DOM structure is malformed.
How to fix it
-
Locate every
<td>element flagged by the validator. -
Ensure it is a direct child of a
<tr>element. -
Ensure that
<tr>is itself inside a<table>,<thead>,<tbody>, or<tfoot>. -
If the
<td>was outside a table entirely, either wrap it in a full table structure or replace it with a more appropriate element like a<div>or<span>.
Examples
<td> directly inside <table> without <tr>
This is the most common cause. The <td> elements are children of <table> but lack a wrapping <tr>:
<!-- ❌ Bad: td is a direct child of table -->
<table>
<td>Name</td>
<td>Email</td>
</table>
Wrap the cells in a <tr>:
<!-- ✅ Good: td is inside a tr -->
<table>
<tr>
<td>Name</td>
<td>Email</td>
</tr>
</table>
<td> directly inside <tbody> without <tr>
<!-- ❌ Bad: td is a direct child of tbody -->
<table>
<tbody>
<td>Alice</td>
<td>alice@example.com</td>
</tbody>
</table>
<!-- ✅ Good: td is wrapped in a tr inside tbody -->
<table>
<tbody>
<tr>
<td>Alice</td>
<td>alice@example.com</td>
</tr>
</tbody>
</table>
<td> used outside any table context
Sometimes a <td> ends up outside a table entirely, perhaps from a copy-paste error or a templating mistake:
<!-- ❌ Bad: td has no table ancestor -->
<div>
<td>Some content</td>
</div>
If you intended to display content in a non-tabular layout, use an appropriate element instead:
<!-- ✅ Good: use a span or div for non-tabular content -->
<div>
<span>Some content</span>
</div>
Missing or misspelled <tr> tag
A typo can leave <td> elements orphaned:
<!-- ❌ Bad: opening tr tag is misspelled -->
<table>
<t>
<td>Price</td>
<td>$9.99</td>
</t>
</table>
<!-- ✅ Good: correct tr element -->
<table>
<tr>
<td>Price</td>
<td>$9.99</td>
</tr>
</table>
Complete table with proper structure
For reference, here is a well-structured table using <thead>, <tbody>, <th>, and <td> — all correctly nested:
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Widget</td>
<td>$4.99</td>
</tr>
<tr>
<td>Gadget</td>
<td>$14.99</td>
</tr>
</tbody>
</table>
Find issues like this automatically
Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.