Fixing Heading Hierarchy Problems
Creating Proper Heading Hierarchies
Headings provide structure to your content and are essential for screen reader users to navigate pages efficiently. A proper heading hierarchy creates a document outline that makes content scannable and understandable.
Why Heading Hierarchy Matters
Screen reader users often navigate by headings:
- Jump between sections quickly using heading navigation
- Understand page structure without reading everything
- Skip to relevant content efficiently
WCAG Requirements
1.3.1 Info and Relationships (Level A): The heading structure must reflect the document's logical organization.
2.4.6 Headings and Labels (Level AA): Headings must describe topic or purpose.
2.4.10 Section Headings (Level AAA): Section headings are used to organize content.
Correct Heading Structure
Headings should form a logical outline, like a book's table of contents:
<h1>Web Accessibility Guide</h1>
<h2>Understanding WCAG</h2>
<h3>The Four Principles</h3>
<h3>Conformance Levels</h3>
<h2>Common Issues</h2>
<h3>Missing Alt Text</h3>
<h4>How to Fix</h4>
<h4>Testing</h4>
<h3>Form Labels</h3>
<h2>Testing Methods</h2>Common Heading Mistakes
Mistake 1: Skipping Heading Levels
<!-- Bad: Jumps from h1 to h3 -->
<h1>Main Title</h1>
<h3>Section Title</h3>
<!-- Good: Proper sequence -->
<h1>Main Title</h1>
<h2>Section Title</h2>Mistake 2: Multiple h1 Elements
While HTML5 technically allows multiple h1s in sectioning elements, it's best practice to have one h1 per page:
<!-- Potentially confusing -->
<h1>Website Name</h1>
<h1>Page Title</h1>
<!-- Better: Clear hierarchy -->
<h1>Page Title</h1>
<p>On Website Name</p>
<!-- Or in header -->
<header>
<p class="site-name">Website Name</p>
<h1>Page Title</h1>
</header>Mistake 3: Using Headings for Styling
<!-- Bad: Using h4 because it's the right font size -->
<h4>This needs to look like a heading but isn't a real section</h4>
<!-- Good: Use CSS for styling, headings for structure -->
<p class="styled-heading">This is styled text, not a heading</p>
<!-- Or if it IS a section heading, use proper level -->
<h2 class="small-heading">Actual Section Title</h2>Mistake 4: Missing Page h1
<!-- Bad: No h1 on the page -->
<header>
<nav>...</nav>
</header>
<main>
<h2>First Section</h2>
</main>
<!-- Good: Page has an h1 -->
<header>
<nav>...</nav>
</header>
<main>
<h1>Page Title</h1>
<h2>First Section</h2>
</main>Heading Best Practices
1. Use Descriptive Text
<!-- Bad: Vague headings -->
<h2>Introduction</h2>
<h2>Section 1</h2>
<h2>More Information</h2>
<!-- Good: Descriptive headings -->
<h2>What is Web Accessibility?</h2>
<h2>Understanding WCAG Guidelines</h2>
<h2>Getting Started with AccessibilityMonitor</h2>2. Keep Headings Concise
<!-- Too long -->
<h2>This Is a Very Long Heading That Tries to Explain Everything
About the Topic in Just One Line Which Makes It Hard to Scan</h2>
<!-- Better: Concise -->
<h2>Getting Started</h2>
<p>Everything you need to know to begin using our platform effectively.</p>3. Front-Load Keywords
<!-- Keywords buried -->
<h2>Learn About the Basics of Web Accessibility</h2>
<!-- Keywords up front -->
<h2>Web Accessibility Basics</h2>Framework Examples
React/Next.js
function ArticlePage({ article }) {
return (
<article>
<h1>{article.title}</h1>
{article.sections.map((section) => (
<section key={section.id}>
<h2>{section.title}</h2>
{section.content}
{section.subsections?.map((sub) => (
<div key={sub.id}>
<h3>{sub.title}</h3>
{sub.content}
</div>
))}
</section>
))}
</article>
);
}Generating Dynamic Heading Levels
function Heading({ level, children, ...props }) {
const Tag = `h${Math.min(level, 6)}`; // Cap at h6
return <Tag {...props}>{children}</Tag>;
}
// Usage
<Heading level={sectionDepth + 1}>Section Title</Heading>Testing Heading Structure
1. Use Browser Extensions
Tools like HeadingsMap or Web Developer Toolbar show heading outlines.
2. Screen Reader Navigation
- NVDA/JAWS: Press H to navigate by headings
- VoiceOver: Use rotor (VO + U) and select Headings
- Listen for proper sequence and descriptive titles
3. Automated Testing
AccessibilityMonitor detects:
- Missing h1
- Skipped heading levels
- Improper heading order
Heading Checklist
- Page has exactly one h1
- Headings don't skip levels
- Headings describe their sections
- Headings aren't used for styling only
- All major sections have headings
- Heading text is concise and descriptive
Was this article helpful?