Lighthouse audit heading-order · Accessibility

Heading elements not in sequentially-descending order: how to fix it

View raw .md for LLMs / your notes

This Lighthouse audit fails when your page skips heading levels, for example, an <h1> followed by an <h3> with no <h2> between them. Screen readers expose the heading hierarchy as a document outline; skipped levels break that outline.

TL;DR

What the audit checks

Lighthouse walks the rendered DOM in source order and inspects every heading (<h1><h6>). It flags pages where a heading is more than one level lower than the previous one.

<h1>Page title</h1>
<h3>Subheading</h3>  <!-- ❌ skipped h2 -->

Going back up is fine, <h3> followed by <h2> is OK. The audit only fails on downward jumps.

Why it matters

Screen readers expose page structure as a navigable outline. Users press H (or NVDA: 1, 2, 3 keys for specific levels) to jump between sections. When levels are skipped, the outline reads as: "Page title (level 1), Subheading (level 3, level 2 missing)." It implies there's a level 2 they missed, which is confusing.

It also hurts SEO subtly: Google's structured understanding of your page relies in part on the heading outline.

The fix

Use heading levels semantically, not visually. Pick the tag for what the content means, then size it with CSS.

<!-- BEFORE: tag chosen for visual size -->
<h1>Our pricing plans</h1>
<h3>Free tier</h3>
<h3>Pro tier</h3>

<!-- AFTER: semantic hierarchy -->
<h1>Our pricing plans</h1>
<h2>Free tier</h2>
<h2>Pro tier</h2>

If you want <h2> to look smaller than the original <h3>, do that in CSS:

h2 { font-size: 1.5rem; font-weight: 600; }

Common scenarios

Scenario: Card grids inside a section

<section>
  <h2>Features</h2>           <!-- correct level for the section -->
  <article>
    <h3>Real-time sync</h3>   <!-- h3 because it's nested in h2's section -->
    <p>...</p>
  </article>
  <article>
    <h3>Offline mode</h3>     <!-- also h3, sibling article -->
    <p>...</p>
  </article>
</section>

Scenario: Sidebar with its own headings

The page's main <main> outline doesn't include <aside> content. You can restart heading levels inside an <aside> if you want, but most accessibility experts recommend continuing the document hierarchy.

Scenario: Component libraries (e.g. design systems)

If your design system exports a <Card> component that hard-codes <h3> internally, you'll break heading order whenever you use it inside a section that doesn't have an h2. Solution: make the heading level a prop.

<Card heading="h2" title="Feature name" />

Pitfalls to avoid

Verification

  1. Re-run Lighthouse. The heading-order audit should pass.
  2. View the document outline with a screen reader's heading list (VoiceOver: VO+U → Headings; NVDA: NVDA+F7).
  3. Use a browser extension like "Headings Map" or axe DevTools to visualize the heading tree.

Related audits


Audit your URL at https://lighthouse-md.com.

Audit your page now

Paste your URL, get scores plus a CLAUDE.md plan for Claude Code.

Run audit →