# The element “h4” must not appear as a descendant of the “th” element.

> Canonical HTML version: https://rocketvalidator.com/html-validation/the-element-h4-must-not-appear-as-a-descendant-of-the-th-element
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

The `th` element already carries semantic meaning as a table header cell. Nesting a heading element like `h4` inside it creates a conflict in the document's outline and semantic structure. Screen readers and other assistive technologies treat headings and table headers as distinct navigational landmarks, so combining them can confuse users who rely on these tools to understand page structure. A heading buried inside a table cell may break the expected heading hierarchy, making it harder for users to navigate by headings.

According to the HTML specification, the content model of `th` is "flow content, but with no header, footer, sectioning content, or heading content descendants." This means `h1`, `h2`, `h3`, `h4`, `h5`, and `h6` are all explicitly disallowed inside `th`.

The reason developers often place headings inside `th` is to achieve a specific visual style — larger, bolder text. But `th` elements are already rendered bold by default in most browsers, and any additional styling should be handled with CSS rather than repurposing heading elements.

## How to Fix It

1. **Remove the heading element** from inside the `th` and use the text directly.
2. **Style with CSS** if you need the `th` content to look different from default styling.
3. **Move the heading outside the table** if it serves as a title or caption for the table. Consider using the `<caption>` element for table titles.

## Examples

### ❌ Incorrect: Heading inside `th`

```html
<table>
  <tr>
    <th><h4>Product</h4></th>
    <th><h4>Price</h4></th>
  </tr>
  <tr>
    <td>Widget</td>
    <td>$25</td>
  </tr>
</table>
```

This triggers the validation error because `h4` elements are not allowed as descendants of `th`.

### ✅ Fixed: Plain text in `th`

```html
<table>
  <tr>
    <th>Product</th>
    <th>Price</th>
  </tr>
  <tr>
    <td>Widget</td>
    <td>$25</td>
  </tr>
</table>
```

The simplest fix — just remove the heading tags. The `th` element already conveys that these cells are headers.

### ✅ Fixed: Using CSS for custom styling

If you need the header cells to have a specific visual appearance, use CSS:

```html
<table>
  <tr>
    <th class="styled-header">Product</th>
    <th class="styled-header">Price</th>
  </tr>
  <tr>
    <td>Widget</td>
    <td>$25</td>
  </tr>
</table>

<style>
  .styled-header {
    font-size: 1.2em;
    text-transform: uppercase;
  }
</style>
```

### ✅ Fixed: Moving the heading outside and using `caption`

If the heading was meant to serve as a title for the table, use the `<caption>` element instead:

```html
<table>
  <caption>Product Pricing</caption>
  <tr>
    <th>Product</th>
    <th>Price</th>
  </tr>
  <tr>
    <td>Widget</td>
    <td>$25</td>
  </tr>
</table>
```

The `<caption>` element is purpose-built for labeling tables and is well-supported by assistive technologies. You can also place a heading before the table if it fits your document's heading hierarchy:

```html
<h4>Product Pricing</h4>
<table>
  <tr>
    <th>Product</th>
    <th>Price</th>
  </tr>
  <tr>
    <td>Widget</td>
    <td>$25</td>
  </tr>
</table>
```

Both approaches keep your HTML valid while preserving clear semantics for both visual users and assistive technology.
