You're In The Right Place If…
- Lighthouse Accessibility flags "Heading elements are not in a sequentially-descending order" and lists elements like an H4 or H5 sitting directly above an H2
- The flagged element is a small label above a big headline — an "eyebrow" like "TURN VISION INTO VALUE" or "OUR SERVICES" — not a real section title
- Your page jumps levels: H1 → H3 with no H2, or an H5 appears before any H4 exists
- The page LOOKS perfectly fine — the problem is invisible unless you read the HTML or use a screen reader
Headings Are Structure, Not Styling
Assistive technologies compile every H1–H6 on your page into a navigable outline — screen-reader users pull up that outline and jump straight to the section they want. Google's crawler reads the same outline to understand what your page is about and how topics relate: an H3 under an H2 is understood as a sub-topic of it. Both consumers assume the levels are hierarchical, because that is what the HTML spec says they are.
The moment a heading level is chosen for its LOOKS — "H4 is small and grey, that matches the mock-up" — the outline stops describing the page. Nothing visibly breaks, which is why this bug ships so often: the only users who notice are the ones navigating by structure, and they notice immediately.
The Eyebrow Anti-Pattern (the Real Culprit)
An eyebrow (also called a kicker or overline) is the small label above a headline — "TURN VISION INTO VALUE" sitting above "Your partner for digital transformation". Visually it comes first, so it feels like it outranks the headline. Semantically it is the opposite: it is a decoration, an aside, a category label. It introduces nothing that the document outline needs to know about.
Marked up as a heading, it creates two problems at once. First, the skip: the H4 eyebrow followed by the H2 headline is a descending-order violation in every section that uses the component. Second, the noise: screen-reader users jumping by headings land on "TURN VISION INTO VALUE" — a fragment with no content under it — before every real section. Multiply by eight sections and the page outline is half garbage.
<!-- WRONG — the eyebrow is not a heading: -->
<h4 class="eyebrow">TURN VISION INTO VALUE</h4>
<h2>Your partner for digital transformation</h2>
<!-- RIGHT — decorative label as a <p>, heading order intact: -->
<p class="eyebrow">Turn vision into value</p>
<h2>Your partner for digital transformation</h2>
/* The looks live in CSS, not in the tag choice: */
.eyebrow {
font-size: 0.8125rem;
font-weight: 600;
letter-spacing: 0.12em;
text-transform: uppercase; /* caps via CSS, not typed caps —
screen readers may spell out typed ALL-CAPS letter by letter */
color: #6b7280;
margin-bottom: 0.5rem;
} The Other Classic Skips (and Their Fixes)
- H1 → H3 because "H2 looked too big": restyle H2 with CSS; never skip to a smaller tag for its font size
- Card titles as H5 inside an H2 section with nothing between: cards directly under an H2 section heading should be H3 — the level is about nesting depth, not importance
- Widget/theme headings you cannot easily change (footer "Quick Links" as H4): make them match their real depth, or if they are purely decorative, swap to a styled <p> exactly like the eyebrow
- Multiple H1s or a logo wrapped in an H1 on every page: one H1 per page, and it should be the page's actual title — the logo belongs in a <div> or <p> everywhere except perhaps the homepage
How To Find Every Violation In One Pass
You do not need to read the source line by line. Paste this into the DevTools console on any page — it prints every heading in order with its level, and flags each place the level jumps by more than one:
// List every heading + flag skipped levels — paste into DevTools console:
let last = 0;
document.querySelectorAll('h1,h2,h3,h4,h5,h6').forEach((h) => {
const lvl = +h.tagName[1];
const skip = lvl > last + 1 ? ' ⚠️ SKIPPED (prev H' + last + ')' : '';
console.log('H' + lvl + ': ' + h.textContent.trim().slice(0, 60) + skip);
last = lvl;
}); Does This Affect SEO Or Just Accessibility?
Google has said heading order is not a direct ranking factor — John Mueller has repeatedly noted that Google copes with imperfect heading structures. But three indirect effects are real. Headings are one of the strongest on-page signals of topic structure, and a coherent outline helps Google (and now AI answer engines quoting your content) extract and attribute sections correctly. Accessibility failures cap your Lighthouse score, which teams increasingly treat as a quality gate. And in several jurisdictions (ADA in the US, EAA in the EU, AODA in Ontario) WCAG conformance is a legal exposure question — heading structure is a WCAG 1.3.1 issue, and it is one of the cheapest to fix.
The Fix, Step By Step
- 1
List the page's heading outline
Run the console snippet above (or a browser extension like HeadingsMap) to print every H1–H6 in document order with skipped levels flagged. Lighthouse's audit details also list each offending element.
- 2
Classify each flagged heading: real section title, or decoration?
For each violation ask: does content belong "under" this text in a table of contents? Eyebrows, kickers, taglines, and labels fail that test — they are decoration.
- 3
Convert decorative headings to <p> with a class
Swap <h4 class="eyebrow"> to <p class="eyebrow"> and move all styling (size, weight, letter-spacing, uppercase) into CSS. Do this in the shared component/template so it fixes every section at once.
- 4
Re-level the real headings so no level is skipped
Within each section, the first heading after an H2 should be H3, then H4 inside that, and so on. Going back UP (H4 back to H2 when a new section starts) is fine — only downward skips fail.
- 5
Keep exactly one H1 per page
The H1 is the page title. Logos, site names, and banner slogans are not H1s on inner pages.
- 6
Re-run Lighthouse and spot-check with a screen reader
The audit should pass. For a real-world check, open VoiceOver (Cmd+F5 on Mac) or NVDA and navigate by headings (the H key in NVDA) — the outline you hear should read like a sensible table of contents.
From the trenches
How we hit this on a real production site
This came out of a live audit of a large B2B consultancy site this week. Lighthouse Accessibility flagged "Heading elements are not in a sequentially-descending order", pointing at an H4 reading "TURN VISION INTO VALUE" sitting directly above the H2 headline of the hero section. Classic eyebrow anti-pattern: the theme's H4 style happened to match the design, so the eyebrow shipped as an H4 — in every section, on every page.
The fix took minutes because it lived in one shared component: the eyebrow tag changed from <h4> to <p class="eyebrow">, the caps moved from typed text into text-transform: uppercase, and the real headings below needed no re-ordering at all — they had been correct all along, the decoration was just polluting the outline.
Accessibility went to 100 on the next run. If your Lighthouse report is showing the same audit, check your eyebrows first — in our client audits it is the cause more often than every other heading mistake combined. And if you would rather have someone sweep your whole site for this and the rest of the WCAG quick wins, that is exactly what our audits do.
Frequently Asked Questions
The eyebrow appears above my H2 — shouldn't it be a HIGHER heading level then?
No. Visual position and semantic rank are independent. The eyebrow is not a title that content sits under — it is a decorative label attached to the headline below it. Text that introduces no subsection belongs in a <p> or <span>, regardless of where it sits visually.
Will fixing heading order improve my Google rankings?
Not directly — Google says it tolerates imperfect heading structure. Indirectly: a clean outline helps search engines and AI answer engines parse and quote your sections correctly, and it removes a Lighthouse Accessibility cap. Treat it as a structure-quality and legal-exposure fix with a small SEO tailwind, not a ranking hack.
Is it OK to go from an H4 back up to an H2?
Yes. Closing a subsection and starting a new section (H4 → H2) is normal document structure. The audit only fails DOWNWARD skips — jumping from H2 to H4 without an H3 in between.
My CMS theme controls the heading tags. What can I do?
Most page builders (WordPress blocks, Elementor, Webflow, Shopify sections) let you change a heading widget's tag independently of its style — look for an "HTML tag" dropdown. If the theme hard-codes it, override the template or ask the theme author; hiding the element from screen readers with aria-hidden is a last resort and loses the text for everyone using assistive tech.
Should I use ALL CAPS in the text or CSS text-transform?
CSS. Some screen readers spell out typed capitals letter-by-letter ("T-U-R-N..."), and typed caps lock the styling into the content. Write the text in normal case and apply text-transform: uppercase in the stylesheet.
Still stuck? Send us the exact error.
Paste the exact error message you're seeing and where it happens. We'll take a look — if it's quick we'll point you at the fix, and if it's deeper we'll tell you honestly what it takes.