Guías HTML para h2
Aprende a identificar y corregir errores comunes de validación HTML marcados por el W3C Validator, para que tus páginas cumplan con los estándares y se muestren correctamente en todos los navegadores. También consulta nuestras Guías de accesibilidad.
The dt element represents a term or name in a description list (dl). According to the HTML specification, its content model is restricted to phrasing content, which means it can only contain text-level elements. Heading elements (h1 through h6) are flow content, not phrasing content, so nesting them inside a dt is invalid HTML.
This restriction exists because dt is designed to label or name something, while headings define the structural outline of a document. Mixing the two creates conflicting semantics — screen readers and other assistive technologies may misinterpret the document’s heading hierarchy, leading to a confusing experience for users navigating by headings. Browsers may also handle the invalid nesting inconsistently, potentially breaking the layout or the logical structure of the description list.
This issue commonly arises when developers want to visually style a definition term as a heading. The correct approach is to either restructure the markup so the heading sits outside the dt, or to style the dt directly with CSS to achieve the desired visual appearance without misusing heading elements.
How to fix it
You have several options:
- Move the heading before the description list. If the heading introduces a group of terms, place it above the dl element.
- Place the heading inside a dd element instead. The dd element accepts flow content, so headings are valid there.
- Style the dt with CSS. If you only need the term to look like a heading, apply font size, weight, and other styles directly to the dt without wrapping its content in a heading element.
Examples
❌ Invalid: heading inside a dt
<dl>
<dt>
<h2>API Reference</h2>
</dt>
<dd>Documentation for the public API.</dd>
</dl>
The h2 is a descendant of dt, which violates the content model.
✅ Valid: heading placed before the description list
<h2>API Reference</h2>
<dl>
<dt>Endpoint</dt>
<dd>The URL used to access the API.</dd>
</dl>
When the heading introduces the entire list, placing it before the dl is the cleanest solution.
✅ Valid: heading inside a dd element
<dl>
<dt>API Reference</dt>
<dd>
<h2>Overview</h2>
<p>Documentation for the public API.</p>
</dd>
</dl>
The dd element accepts flow content, so headings are permitted there.
✅ Valid: styling the dt to look like a heading
<style>
.term-heading {
font-size: 1.5em;
font-weight: bold;
}
</style>
<dl>
<dt class="term-heading">API Reference</dt>
<dd>Documentation for the public API.</dd>
</dl>
This approach gives you the visual appearance of a heading while keeping the markup valid. Keep in mind that styled dt elements won’t appear in the document’s heading outline, so only use this when a true heading isn’t semantically needed.
✅ Valid: using a span for inline styling inside dt
<dl>
<dt><span class="term-heading">API Reference</span></dt>
<dd>Documentation for the public API.</dd>
</dl>
Since span is phrasing content, it’s perfectly valid inside dt and gives you a styling hook without breaking the content model.
The HTML specification defines a strict content model for the th element: it accepts flow content, but specifically excludes header, footer, sectioning content, and heading content (h1–h6). This restriction exists because th elements are themselves headers — they describe the data in their corresponding row or column. Placing a heading element inside a th creates a conflict in the document outline and semantic structure.
This matters for several reasons:
- Accessibility: Screen readers use headings to build a navigable document outline. Headings buried inside table header cells can confuse assistive technology, making it harder for users to understand the page structure and navigate between sections.
- Document outline: Heading elements define the hierarchical structure of a document’s content. When headings appear inside table cells, they disrupt this hierarchy and create unexpected, often meaningless, sections in the outline.
- Standards compliance: Browsers may handle this invalid nesting inconsistently, and the W3C validator will flag it as an error.
A common reason developers place headings in th cells is to achieve a specific visual style — larger or bolder text. The correct approach is to use CSS to style the th content directly, keeping the markup clean and valid.
How to Fix It
- Remove the heading element from inside the th.
- Move the heading above the table if you need a title or section heading for the table.
- Use CSS to style the th text if you need a particular visual appearance.
- Use the caption element if you want to provide a visible title that is semantically associated with the table.
Examples
❌ Incorrect: Heading inside a th element
<table>
<tr>
<th><h2>Product</h2></th>
<th><h2>Price</h2></th>
</tr>
<tr>
<td>Widget</td>
<td>$25</td>
</tr>
</table>
This triggers the validation error because h2 elements are not permitted as descendants of th.
✅ Correct: Plain text inside th, heading moved outside
<h2>Product Pricing</h2>
<table>
<tr>
<th>Product</th>
<th>Price</th>
</tr>
<tr>
<td>Widget</td>
<td>$25</td>
</tr>
</table>
✅ Correct: Using caption for the table title
<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 the semantically appropriate way to give a table a title. It is announced by screen readers in context with the table, providing a better experience than a heading placed before the table.
✅ Correct: Styling th with CSS for visual emphasis
If the heading was added purely for visual effect, use CSS instead:
<style>
.prominent-header th {
font-size: 1.5em;
font-weight: bold;
color: #333;
}
</style>
<table class="prominent-header">
<tr>
<th>Product</th>
<th>Price</th>
</tr>
<tr>
<td>Widget</td>
<td>$25</td>
</tr>
</table>
This gives you full control over the appearance of header cells without breaking the document structure or introducing validation errors. Remember: th elements are already semantically headers, so there’s no need to wrap their content in heading elements.
¿Listo para validar tus sitios?
Comienza tu prueba gratuita hoy.