HTML Guides for h1
Learn how to identify and fix common HTML validation errors flagged by the W3C Validator — so your pages are standards-compliant and render correctly across every browser. Also check our Accessibility Guides.
The HTML heading elements <h1> through <h6> define a document’s heading hierarchy. The <h1> element represents the highest-level heading, and each subsequent level (<h2>, <h3>, etc.) represents a deeper subsection. This hierarchy is critical for both accessibility and document structure.
The HTML5 specification once introduced a “document outline algorithm” that would have allowed multiple <h1> elements to be automatically scoped by their parent sectioning elements (<section>, <article>, <nav>, <aside>). Under this model, an <h1> inside a nested <section> would be treated as a lower-level heading. However, no browser or assistive technology ever implemented this algorithm. The outline algorithm was eventually removed from the WHATWG HTML specification. In practice, screen readers and other tools treat every <h1> on a page as a top-level heading, regardless of nesting.
This matters for several reasons:
- Accessibility: Screen reader users frequently navigate by headings to get an overview of a page’s content. When multiple <h1> elements exist, the heading list becomes flat and unclear, making it difficult to understand the page’s structure and find specific content.
- SEO: Search engines use heading hierarchy to understand page structure and content importance. Multiple <h1> elements can dilute the semantic signal of your primary page topic.
- Standards compliance: While using multiple <h1> elements is not a validation error, the W3C validator raises this as a warning because it is widely considered a best practice to reserve <h1> for the single, top-level page heading.
To fix this warning, follow these guidelines:
- Use exactly one <h1> per page to describe the main topic or title.
- Use <h2> for major sections beneath it, <h3> for subsections within those, and so on.
- Don’t skip heading levels (e.g., jumping from <h1> to <h3> without an <h2>).
Examples
Incorrect: Multiple <h1> elements
This example uses <h1> inside each sectioning element, which triggers the warning. Screen readers will present all three headings at the same level, losing the intended hierarchy.
<h1>My Blog</h1>
<section>
<h1>Latest Posts</h1>
<article>
<h1>How to Write Accessible HTML</h1>
<p>Writing semantic HTML is important for accessibility.</p>
</article>
<article>
<h1>Understanding CSS Grid</h1>
<p>CSS Grid makes complex layouts straightforward.</p>
</article>
</section>
Correct: Proper heading hierarchy
Use a single <h1> for the page title and nest subsequent headings using the appropriate levels.
<h1>My Blog</h1>
<section>
<h2>Latest Posts</h2>
<article>
<h3>How to Write Accessible HTML</h3>
<p>Writing semantic HTML is important for accessibility.</p>
</article>
<article>
<h3>Understanding CSS Grid</h3>
<p>CSS Grid makes complex layouts straightforward.</p>
</article>
</section>
Incorrect: <h1> nested inside a section without a parent heading
Even a single <h1> nested deeply inside sectioning content can trigger this warning if the structure suggests it is not the page’s primary heading.
<section class="about">
<article>
<h1>Article heading</h1>
<p>Lorem ipsum dolor sit amet.</p>
</article>
</section>
Correct: Section with its own heading and properly ranked article heading
<section class="about">
<h1>About</h1>
<article>
<h2>Article heading</h2>
<p>Lorem ipsum dolor sit amet.</p>
</article>
</section>
Correct: Full page structure with clear heading hierarchy
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Company Homepage</title>
</head>
<body>
<header>
<h1>Acme Corporation</h1>
</header>
<main>
<section>
<h2>Our Services</h2>
<h3>Web Development</h3>
<p>We build modern, accessible websites.</p>
<h3>Design</h3>
<p>Our design team creates beautiful interfaces.</p>
</section>
<section>
<h2>About Us</h2>
<p>We have been in business since 2005.</p>
</section>
</main>
</body>
</html>
In this structure, screen readers will present a clear, navigable outline: one top-level heading followed by properly nested subheadings that reflect the logical organization of the content.
The th element has a specific role in HTML: it defines a header cell within a table. It already carries implicit heading semantics through its association with the rows or columns it describes. When you place an h1–h6 element inside a th, you’re nesting one type of heading structure inside another, which violates the HTML content model. The HTML specification explicitly excludes heading elements from the allowed content of th.
This causes several problems:
- Document outline confusion: Heading elements contribute to the document’s outline and sectioning structure. Placing them inside table headers injects unexpected entries into the outline that don’t represent actual document sections, making navigation unpredictable.
- Accessibility issues: Screen readers treat headings and table headers differently. A heading inside a th creates conflicting signals—assistive technology may announce the content as both a table header and a document heading, confusing users who rely on either navigation method.
- Standards compliance: Browsers may handle this invalid nesting inconsistently, leading to unpredictable rendering or behavior across different environments.
If your goal is to make the text inside a th visually larger or bolder, use CSS instead. The th element is already rendered bold by default in most browsers, and you can further style it with font-size, font-weight, or any other CSS property.
Examples
Incorrect: heading inside a th element
<table>
<tr>
<th><h1>Product</h1></th>
<th><h1>Price</h1></th>
</tr>
<tr>
<td>Widget</td>
<td>$25</td>
</tr>
</table>
This triggers the validation error because h1 elements are nested inside th elements.
Fixed: plain text in th, heading moved outside the table
<h1>Product Pricing</h1>
<table>
<tr>
<th>Product</th>
<th>Price</th>
</tr>
<tr>
<td>Widget</td>
<td>$25</td>
</tr>
</table>
The heading now introduces the table as a whole, and the th elements contain plain text.
Fixed: styling th with CSS instead of using headings
If you want the table headers to have a specific visual appearance, apply CSS directly to the th elements:
<style>
.styled-table th {
font-size: 1.5rem;
font-weight: bold;
text-transform: uppercase;
}
</style>
<table class="styled-table">
<tr>
<th>Product</th>
<th>Price</th>
</tr>
<tr>
<td>Widget</td>
<td>$25</td>
</tr>
</table>
Fixed: using caption for a table title
If the heading was meant to serve as a title for the table, the caption element is the semantically correct choice:
<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 specifically designed to label a table and is properly associated with it for assistive technology. You can style it with CSS to achieve any visual appearance you need.
Ready to validate your sites?
Start your free trial today.