Broken Heading Hierarchy (Skipping Levels)
WAVE (Error: Skipped heading level, Possible heading), axe DevTools (rule: heading-order), Lighthouse (accessibility audit), Pa11y
Why it matters
Headings are the primary navigation mechanism for screen reader users on long pages. Screen readers allow users to jump from heading to heading using keyboard shortcuts (H key in NVDA/JAWS, Ctrl+Option+Cmd+H in VoiceOver), building a mental model of the page structure similar to a document outline. When headings skip levels, users lose orientation — they cannot tell whether they are in a sub-section or a new major section. A page that jumps from H2 to H4 tells the screen reader user "there must be an H3 section I missed" causing them to search backward for non-existent content. For people with cognitive disabilities, proper heading hierarchy enables predictable navigation that reduces cognitive load. Search engines also use heading structure to understand page topics and sub-topics.
Symptoms — what you'll see
If your site has this problem, you may observe any of the following:
- Page jumps from H1 to H3, or H2 to H4, skipping levels
- Multiple H1 elements on a single page (only one H1 should exist per page)
- No H1 element on the page at all
- Headings used for visual styling (large bold text) rather than document structure
- Heading levels chosen based on desired font size, not content hierarchy
- Screen reader heading navigation jumps confusingly
- WAVE flags "Missing heading" or heading level skip errors
- axe DevTools reports heading-order violations
Common causes
- Choosing heading levels by visual size (H4 looks like the size I want) rather than hierarchy
- Copy-pasting content from different sections that had different heading structures
- CMS WYSIWYG editors that make it easy to choose heading styles visually
- Component library headings with hardcoded levels that don't flex to context
- Adding new content sections without checking the existing heading structure
- Marketing teams adding styled "heading-like" elements using H1 for impact
- Page builders (Elementor, Webflow, Divi) that allow arbitrary heading selection
How to fix it
- 1Use WAVE to visualize your page's heading structure — click the "Structure" view to see headings in order.
- 2Ensure exactly one H1 per page that describes the page's main topic.
- 3Structure headings as an outline: H1 (page title) > H2 (major sections) > H3 (sub-sections) > H4 (sub-sub-sections).
- 4Never skip levels in the sequence — going from H2 to H4 skips H3 and is a violation.
- 5If a heading needs to look like a smaller size, use CSS to style it rather than using a lower heading level.
- 6If a heading needs to look larger for visual reasons, keep the correct semantic level and override font-size via CSS.
- 7Do not use headings for styling purposes — use <p>, <strong>, or CSS classes instead.
- 8Review dynamically-loaded content: SPA route changes and AJAX-loaded sections must maintain correct heading nesting.
Code example
<!-- BROKEN: skips H2, jumps H1 to H3 -->
<h1>Web Accessibility Guide</h1>
<h3>What is WCAG?</h3> <!-- WRONG: skipped H2 -->
<h5>WCAG Principles</h5> <!-- WRONG: skipped H4 -->
<h3>How to Test</h3>
<!-- BROKEN: multiple H1s on same page -->
<h1>Homepage</h1>
<!-- ... -->
<h1>Featured Products</h1> <!-- WRONG: second H1 --><!-- FIXED: proper heading hierarchy -->
<h1>Web Accessibility Guide</h1>
<h2>What is WCAG?</h2>
<h3>WCAG Principles</h3>
<h2>How to Test</h2>
<h3>Automated Testing Tools</h3>
<h3>Manual Testing Steps</h3>
<!-- FIXED: one H1, sections use H2 -->
<h1>Homepage</h1>
<!-- ... -->
<h2>Featured Products</h2>How to test your fix
After applying the fix, verify it works using these testing steps:
- Run WAVE and click the "Structure" button in the toolbar — it shows all headings in order with their levels.
- Use the HeadingsMap browser extension (Chrome/Firefox) for a visual heading tree.
- Open NVDA or VoiceOver, use headings list (Insert+F7 in NVDA) to see all headings on the page.
- Run axe DevTools and look for "heading-order" violations.
- Manually review page HTML for any <h1> through <h6> elements and verify the hierarchy makes logical sense as an outline.
Frequently asked questions
Can a page have more than one H1?+
HTML5 specification allows multiple H1 elements when used in sectioning elements (<article>, <section>). However, WCAG best practice and screen reader conventions favor a single H1 per page. The WebAIM survey found screen reader users predominantly prefer and expect a single H1 that identifies the page. Having multiple H1s can confuse users and weaken SEO.
Is it okay to skip from H3 back to H2?+
Headings do not need to form a strictly ascending sequence throughout the page — you can go from H3 back to H2 when starting a new section at the same level. The rule against skipping applies to going deeper: do not jump from H2 directly to H4. Going from a subsection back to a parent level (H3 to H2) is acceptable and expected.
Can I use CSS to make an H2 look like an H4 to fix the hierarchy?+
Absolutely, and this is the recommended approach. Semantic heading levels and visual heading styles are separate concerns. Use CSS to control font size independently of the heading level. For example, add utility classes like .heading-style-sm that override font-size without changing the semantic level. Never choose a heading level for its default visual size.
What heading level should section headings on the homepage use?+
Homepage sections (Features, Pricing, Testimonials, FAQ) should typically be H2 elements, as the H1 is the company or product name/tagline. Sub-items within sections (individual feature names, individual FAQ questions) should be H3. This creates a clear hierarchy: H1 > H2 (sections) > H3 (items within sections).
How do I handle heading levels in React/Vue components?+
Create heading components that accept a "level" prop (e.g., <Heading level={2}>Section Title</Heading>) so components can be used at the correct heading level in any context, rather than hardcoding <h2> inside a component. This is the pattern used by design systems like Adobe Spectrum and Radix UI.