# “th” start tag in table body.

> Canonical HTML version: https://rocketvalidator.com/html-validation/th-start-tag-in-table-body
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

When you write a `<table>` without explicitly using `<thead>` and `<tbody>`, the HTML parser automatically wraps your `<tr>` elements in an implicit `<tbody>`. If any of those rows contain `<th>` elements intended as column headers, the validator flags them because `<th>` cells in `<tbody>` are unexpected — the parser sees header cells appearing in what should be the data body of the table.

While `<th>` elements are technically valid inside `<tbody>` (for example, as row headers), this warning usually indicates a structural problem: your column headers aren't properly separated from your data rows. Properly structuring your table with `<thead>` and `<tbody>` matters for several reasons:

- **Accessibility:** Screen readers use table structure to help users navigate. A `<thead>` section clearly identifies column headers, making it easier for assistive technology to announce what each data cell represents.
- **Styling and behavior:** CSS selectors like `thead th` and `tbody td` let you target headers and data cells independently. Browsers can also use `<thead>` and `<tbody>` to enable scrollable table bodies while keeping headers fixed.
- **Standards compliance:** Explicitly defining table sections removes ambiguity and ensures consistent parsing across all browsers.

To fix this issue, wrap the row containing your `<th>` column headers in a `<thead>` element, and wrap your data rows in a `<tbody>` element.

## Examples

### ❌ Incorrect: `<th>` in implicit table body

Here, the parser wraps all rows in an implicit `<tbody>`, so the `<th>` elements end up inside the table body:

```html
<table>
  <tr>
    <th>Name</th>
    <th>Age</th>
  </tr>
  <tr>
    <td>Liza</td>
    <td>49</td>
  </tr>
  <tr>
    <td>Joe</td>
    <td>47</td>
  </tr>
</table>
```

### ✅ Correct: `<th>` in explicit `<thead>`

Wrapping the header row in `<thead>` and data rows in `<tbody>` resolves the issue:

```html
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Age</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Liza</td>
      <td>49</td>
    </tr>
    <tr>
      <td>Joe</td>
      <td>47</td>
    </tr>
  </tbody>
</table>
```

### ✅ Correct: `<th>` as row headers inside `<tbody>`

If you intentionally use `<th>` elements inside `<tbody>` as row headers, add the `scope` attribute to clarify their purpose. This is valid and won't trigger the warning when the table also has a proper `<thead>`:

```html
<table>
  <thead>
    <tr>
      <th scope="col">Name</th>
      <th scope="col">Age</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Liza</th>
      <td>49</td>
    </tr>
    <tr>
      <th scope="row">Joe</th>
      <td>47</td>
    </tr>
  </tbody>
</table>
```

The `scope="row"` attribute tells assistive technology that these `<th>` cells are headers for their respective rows, while `scope="col"` identifies column headers. This combination provides the best accessibility for table data.
