Skip to content

Heading levels need to increase by one at most

  • Rule: axe/heading-order
  • Checks: Heading levels should only increase by one
  • WCAG: none; a best practice, not a WCAG success criterion
  • Fix class: mechanical: A fix needs no authored text or visual decision.
  • People who use a screen reader or a braille display, most of them blind.

A level was skipped for a smaller font, such as an <h2> followed by an <h4>

Section titled “A level was skipped for a smaller font, such as an <h2> followed by an <h4>”

Use the next level down, here <h3>, and set its size with CSS. Choose each level from the outline, not from how large the text should look; going back up by any number of levels is fine.

<h2>Plans</h2>
<h3 class="small-heading">Monthly billing</h3>
<p>Pay month to month and cancel at any time.</p>

A shared component hard-codes its heading level

Section titled “A shared component hard-codes its heading level”

Let each page set the level where it places the component: one below the heading of the section it sits in.

Text that is not a heading, such as a price or a tagline, is marked up as one for its look

Section titled “Text that is not a heading, such as a price or a tagline, is marked up as one for its look”

Make it a <p> or a <span> and style it with CSS. Keep heading elements for text that introduces a section.

Replacing headings with styled <div> or <p> elements to clear the rule

Section titled “Replacing headings with styled <div> or <p> elements to clear the rule”

The rule goes quiet, but screen reader users lose those headings, which they use to skim the page and jump between sections.

The part of the fix that differs in React, in its syntax. The rest of the guidance holds.

A shared component hard-codes its heading element

Section titled “A shared component hard-codes its heading element”

Take the level as a prop and render the matching element through a capitalized variable. Each page then passes the level its outline needs.

function Card({ title, headingLevel = 3, children }) {
const Heading = `h${headingLevel}`;
return (
<article>
<Heading>{title}</Heading>
{children}
</article>
);
}

Choosing the heading element from a visual size prop, such as size="small" rendering <h5>

Section titled “Choosing the heading element from a visual size prop, such as size="small" rendering <h5>”

The outline then follows the design instead of the content, and it skips levels wherever a smaller look is wanted. Keep one prop for the level and another for the size.

axe-core’s documentation of the rule

CORA’s fix guidance adapts content from accessibility-agents, under the MIT License: see its notice.