A heading level is a promise, not a font size
Open a Markdown file and an H2 looks like a slightly smaller H1. Open the rendered page and the difference is even more subtle — maybe a point size, maybe a weight change. It’s easy to treat heading levels as a styling choice, one step in a visual hierarchy that exists to make a page look organized. That’s not actually what a heading level is for. It’s a structural claim about how one section relates to another, and plenty of things downstream of your document take that claim completely literally.
A screen reader user can jump between headings the way a sighted reader skims a page, but only if the levels are consistent. A tool that generates a table of contents from your headings has to infer nesting purely from the numbers — it has no other signal. A style guide that says “don’t skip levels” isn’t being pedantic about formatting. It’s protecting the one piece of information that everything else depends on.
What goes wrong when a heading level is skipped
Picture a document with an H2 called “Configuration,” followed directly by an H4 called “Advanced options,” with no H3 in between. To a person reading top to bottom, this barely registers — the H4 just looks like a smaller subheading of the H2, and the meaning comes through fine. To anything parsing the heading levels mechanically, this is a gap with no way to fill it in. Is “Advanced options” a child of “Configuration,” or was there meant to be an H3 here that got deleted during an edit? The levels alone can’t say.
Every tool that builds an outline from your headings — a TOC generator, a screen reader’s heading navigation, a static site generator’s sidebar — has to make some assumption to paper over the gap, and different tools make different assumptions. That’s the real cost of skipping a level: not that any one renderer definitely breaks, but that you’ve handed every renderer an ambiguous instruction and have no control over how each one resolves it.
How many H1s should a document have?
The other common structural mistake is a document with no H1 at all, or with two or three of them. An H1 is supposed to be the title — the one heading that says what the entire page is about, sitting above everything else in the outline. A document with two H1s reads, structurally, as two documents concatenated together, whether or not that was the intent. A document with none has an outline that starts at H2, which is the same skipped-level problem as before, just at the very top.
This one is worth catching early specifically because it’s invisible in a rendered preview. Most static site generators pull the page’s H1 in as the browser tab title or the page heading automatically, so a missing or duplicated H1 often looks completely normal until you check the raw source or the generated table of contents.
Duplicate headings create duplicate anchors
Every heading that gets rendered to HTML also gets an anchor — a short, URL-safe slug derived from its text, so a link can jump straight to that section. The slug comes from a fairly mechanical process: lowercase everything, strip punctuation, replace spaces with hyphens. Two headings with different text can still produce identical slugs after that process runs — “API Setup!” and “API Setup?” both collapse to “api-setup” — and when that happens, a link to one of them may resolve to the other instead, depending on how the specific renderer breaks the tie.
This is a narrower problem than a duplicate heading, and a quieter one. The headings look completely different on the page. Nothing about reading the document would tip you off. The only way to catch it is to actually compute both slugs and compare them, which is exactly the kind of bookkeeping that’s easy for a tool and tedious for a person to do by hand across a long document.
Why headings need parallel structure
Three sibling headings — “Installing the agent,” “Configuration,” and “How to run tests” — are grammatically unrelated to each other: a gerund, a bare noun phrase, and a question. Each one reads fine by itself. Read as a set, the way an outline or a sidebar presents them, the inconsistency shows up immediately, because a heading list is exactly the kind of text a reader scans rather than reads. Scanning depends on pattern-matching shape, and a set of headings that all follow the same grammatical pattern is easier to scan than a set that doesn’t, even when every individual heading is perfectly clear.
The same logic applies to capitalization. Mixing Title Case and sentence case among sibling headings doesn’t make any single heading wrong, but it breaks the visual rhythm a reader’s eye relies on when skimming a list of headings rather than reading full sentences. Consistency here is worth enforcing precisely because no single heading will ever look broken on its own — the defect only exists when you compare it to its neighbors, which is the same structural blind spot behind expanding acronyms on first use: a check that has to hold the whole document in view at once, not just the sentence in front of you.
Sections that are too long, and sections that are too short
A heading with no subheading and a wall of text underneath is hard to scan and impossible to link to a specific point within — if a reader wants to reference paragraph six of an unbroken 800-word section, there’s no anchor for that. The fix is almost always to add a subheading, not to trim the content. The opposite problem — a heading with almost nothing under it — usually means the section should be folded into a neighbor instead of standing alone with one sentence to its name.
Neither threshold is a hard rule. A FAQ entry with a two-sentence answer isn’t a defect; a reference page with an intentionally exhaustive section might legitimately run long. That’s why both thresholds are adjustable rather than fixed — the point isn’t to hit a number, it’s to notice the sections worth a second look.
Check your own document
The heading & document structure checker builds the full outline from a pasted Markdown, HTML, or plain-text document and flags every issue above in one pass: skipped levels, missing or duplicate H1s, slug collisions, non-parallel siblings, case drift, and sections running long or short. It also generates a ready-to-copy Markdown table of contents with working anchors, built the same way a static site generator would build one from the same headings.