Heading Structure Checker

Read the headings of a page with the page removed and you find out whether it has a structure or just some bold text at intervals. That is not a metaphor — it is how a screen reader user moves through a document, jumping heading to heading. Paste the markup and this shows you what they would hear.

Only the heading elements are read. Everything else in the paste is ignored.
Heading Structure Checker — H1 to H6 Outline, Skipped Levels and DuplicatesBuildFigure

What headings are actually for

Heading elements are not a font size. They are the document outline, and for a screen reader user they are the primary way to move around a page — most screen readers offer a key that jumps to the next heading, and a shortcut that lists every heading on the page so the user can pick one. Surveys of screen reader users have consistently put headings at the top of the list of things they use to navigate.

That is what makes an empty h2 or a paragraph marked up as an h4 a real problem rather than a tidiness issue. The person navigating by heading gets an entry in their list that says nothing, or a list where the structure implies a nesting the content does not have.

Skipped levels

Going h2 to h4 leaves an orphan: a heading whose implied parent does not exist. Someone reading the outline sees a subsection of a section that is not there. The fix is almost never to insert a heading — it is to change the h4 to an h3, because the level was chosen for how it looked rather than for what it meant.

This is the single most common finding on a page that has never been checked, and it happens because CSS decoupled appearance from level years ago and nothing forces anyone to notice. If your h3 looks wrong in a particular place, style it; do not renumber it.

The h1 argument, honestly

You will find confident claims in both directions. What is actually true: the HTML specification permits multiple h1 elements, and the outline algorithm that was once meant to make sectioning elements reinterpret heading levels was never implemented by any browser or assistive technology and has been removed from the specification. So multiple h1s are legal, and they do not get automatically demoted by anything.

What follows from that is a preference rather than a rule. One h1, naming what the page is, gives a reader jumping into the outline a single unambiguous anchor. Several h1s make them work out which is the page and which is the site. Neither is an error; one is easier to use. Where multiple h1s usually come from is a template emitting the site name as an h1 in the masthead, and that one is worth fixing because the site name is not what the page is about.

What a heading audit does not tell you

It says nothing about whether the words are good. A perfectly nested outline of headings reading "Introduction", "More", "Details" and "Conclusion" passes every check on this page and tells a reader nothing. Skim your own outline in the text output above and ask whether somebody who saw only that list would know what the page contains. That is the test the structure checks are standing in for.

It also cannot see the page. A heading hidden by CSS, a heading generated by JavaScript, a visual heading built from a styled div — all invisible to a paste of static markup, and the third is worth searching your template for specifically. To look at what the page says rather than how it is structured, the keyword density checker and the reading time estimator work on the text itself, and the contrast checker covers the other half of the accessibility question this page touches.

Fixing an outline without redesigning

Work down the tree once. Set the page title as the only h1. Make each major section an h2. Anything beneath a section is an h3, and so on, one level at a time. Then go back through the CSS and give each level the size it needs, which is usually less work than it sounds because the levels tend to already have the right visual weight in the places they were used correctly.

The related structural pieces are the head tags, which describe the page to things that never render it, and the JSON-LD generator, which restates the content for parsers. All three are describing the same page to different audiences, and they should agree.

Questions people ask

Is more than one h1 an error?

No. The HTML specification allows it, and the outline algorithm that would have reinterpreted heading levels inside sections was never implemented anywhere and has been dropped. It is a usability preference: one h1 gives a person navigating by heading a single anchor for what the page is. The common cause of extra h1s is a template putting the site name in one, and that is worth changing regardless.

Does this check what search engines see?

It checks the markup you pasted, which is a different thing. No one outside a search engine can tell you how heading levels are weighed, and claims that h1 text carries a specific ranking weight are not verifiable. The reason to fix an outline is that it is how some people navigate your page, and that effect is real and measurable in usability testing.

My headings are divs with classes. Does that matter?

For appearance, no. For navigation, yes — a styled div is not in the heading list a screen reader builds, so a user jumping between headings skips it entirely and the page appears to have no structure. If something looks like a heading and functions like one, mark it as one and style it however you like.

Why is my heading not detected?

Three usual reasons. The opening and closing tags do not match, so the pattern that pairs them finds nothing. The heading is generated by JavaScript and is not in the static markup you pasted. Or you are in Markdown mode and the line has no space after the hashes, which is required by most Markdown parsers as well.

Should a heading contain a link, an image or a button?

A link inside a heading is normal and fine — a card title that is also the link to the article, for instance. An image is acceptable if it has alt text, since that text becomes the accessible name of the heading. A button inside a heading is where it gets murky, and the safer pattern for a collapsible section is a button that wraps the heading text with the heading element outside it, so the outline entry stays a heading.

Related