Website problems

Broken heading structure

Heading elements form a document outline: `<h1>` names the page, `<h2>` names its major parts, `<h3>` the parts of those. The outline breaks in three recurring ways — several `<h1>` elements competing to name the page, a level skipped so the nesting no longer follows, and a heading element containing no text at all. All three are invisible on screen and all three matter to anyone navigating by headings rather than by sight.

The outline is the point

A correct heading structure reads like a table of contents. Each level nests inside the one above it, no level is skipped on the way down, and every heading has text.

Screen readers expose that structure directly: users list the headings and jump to the one they want, or move level by level. An outline that jumps from `<h1>` to `<h4>` tells them a level of detail exists that they have missed, and they look for it.

HTML5 once promised that sectioning elements would recalculate heading levels automatically. That outline algorithm was never implemented by browsers or assistive technology and has been removed from the specification. The level you write is the level that is used.

Several H1 elements

HTML permits more than one `<h1>`, and Google has said explicitly that multiple H1s are fine and not a problem for its systems. So this is not an error in the sense of something being invalid.

It is still usually a symptom. The common cause is a layout where the site logo, the page heading and a promotional banner are each marked up as `<h1>` by different components that were never compared. The page then states three subjects, and none of them is clearly the subject.

The exception worth knowing: a page composed of genuinely independent articles — a feed, a digest — can reasonably give each article its own top-level heading.

The test is not the count. It is whether a reader hearing only the H1s would learn what the page is about.

Skipped levels and empty headings

A skipped level is a heading that descends more than one step: `<h2>` followed directly by `<h4>`. It is almost always a styling decision — the author wanted smaller text — and it leaves a gap in the outline that assistive technology reports faithfully.

Going back up is not a skip. `<h3>` followed by `<h2>` simply closes one section and opens another, which is normal.

An empty heading is a heading element with no text: `<h2></h2>`, or one containing only an image with no alternative text, or only a decorative icon. Screen readers announce a heading and then nothing, which is worse than no heading at all.

Empty headings usually come from a CMS field left blank, or from a component that renders its wrapper whether or not it has content.

How to check it yourself

In the console: `[...document.querySelectorAll('h1,h2,h3,h4,h5,h6')].map(h => h.tagName + ' ' + h.textContent.trim())` prints the outline in document order. Read it as a list. If it does not read like a table of contents, it is not one.

Empty headings show up in that same list as a tag name followed by nothing.

Browser developer tools expose the accessibility tree, which shows the computed heading level and accessible name — useful when a heading's text comes from an `aria-label` or an image.

Do this on each template rather than on each page: the outline is generated by the layout, so one representative page per template covers the site.

How to fix it

Decide the outline before the styling. Write the levels the content requires, then make CSS produce the sizes the design requires. A `<h3>` that needs to look large is a CSS rule, not a `<h2>`.

Reduce competing H1s to one unless the page genuinely contains several independent items. A logo is not a heading; it is a link to the home page.

Remove heading elements that have no text, rather than filling them with a space or a non-breaking space to silence a checker.

Where a heading's text is inside an image, give the image alternative text or move the text into the heading.

How VeriFixScan detects it

`seo.h1` reports the H1 count per page, so a page with none and a page with four are both visible. `accessibility.semantic_landmarks` covers the document structure the headings sit inside.

The scanner tags the individual defects with their own codes — a skipped level, an empty heading, several H1s — so a report separates the three causes rather than reporting one undifferentiated 'heading problem'.

What no automated check can decide is whether a heading describes its section well. Levels, counts and emptiness are facts; wording is a review.

Frequently asked questions

Is more than one H1 an error?
No. HTML allows it and Google has stated that multiple H1s are not a problem for its systems. It is worth looking at anyway, because the usual cause is several components each claiming to name the page.
Does skipping from H2 to H4 matter?
It matters to anyone navigating by headings, who is told a level exists that they did not hear. WCAG treats a meaningful heading sequence as part of an accessible structure, and browsers no longer recalculate levels for you.
Can I use headings purely for styling?
You can, and it breaks the outline for people who rely on it. Headings carry structure; CSS carries size. Choosing a level for its default font is the single most common cause of a skipped level.

Sources

Related

VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.

Scan a website