Getting Heading Levels Right - Including Here on DEV

Suzanne Aitchison - Oct 22 '19 - - Dev Community

During Hacktoberfest I spent some time searching for and helping with small accessibility issues in open source projects. One issue I saw coming up time and again was around inappropriate use of heading levels. It's a topic that's come up in comments on some of my posts before, and I feel like if we can shift our approach on heading levels, we can side step some of these a11y issues, and in some cases get a little SEO win too.

Why heading levels matter to accessibility

The most common way for screen reader users to parse your web content is to first navigate by heading level (as detailed in the latest WebAIM screen reader survey results).

This means they will use shortcut commands to scan your headings in order of their level - h1s followed by h2s and so on. This approach directly correlates to the way sighted users consume your web content - instead of scanning what looks like the most important headings, the screen reader infers the order of importance from the level of the heading tag used.

Sequential heading levels allow screen reader users to scan for content

A screen reader user, just like any other user, does not want to read every word of content on a page to find the key information they are looking for.

When a sighted user scans your page they internally process: page purpose → top level content → section content → more detailed content. They can quickly visually interpret the hierarchy of information on the page.

To facilitate the same behaviour for screen reader users, sequential headers can be used: h1 (page purpose) → h2 (top level content) → h3 (next level content).

We need to approach heading levels as an indicator of priority, not style

When speaking to other developers I often find that heading levels are considered an aspect of style. The fact that out-of-the-box browser behaviour results in h1 elements being bigger than h2, and so on, serves to reinforce that point of view.

The result is quite often in web content you'll find an h1 followed by an h4 or some other non-sequential progression. As established above however, heading levels have a semantic purpose. While styling can easily be changed with CSS, semantics can't, and therefore we should shift our way of thinking about heading levels to centre the hierarchy of information on the page.

Every page needs an h1

I can't stress this enough! The h1 element announces what the topic of the current page is, and an indication of what can be found within. For screen reader users it clearly sets the context of the page - omitting it is like a sighted user having to scan a whole page of content just to find out what a page is meant to be about. Similarly, you should only ever have one h1 on your page, as there should be only one 'source of truth' in terms of what the page is for.

I would argue that even sighted users benefit from an h1 element on every page, but if you feel strongly otherwise, remember you can always position your h1 off-screen using CSS so it will be perceivable to screen reader users, but not sighted users.

A descriptive h1 will also benefit your SEO, as it helps crawlers understand your page's content - just like screen readers!

Nest remaining headers, in order of importance

After the h1 element, the next headings should occur in order, never increasing by more than one level. You may have multiple h2s, h3s etc, but for example an h3 should always be a descendant of an h2.

I find the easiest way to think about it is like a tree of information:

Page title (h1)

  • Section title (h2)
    • Sub-heading within section (h3)
    • Sub-heading within section (h3)
  • Second section title (h2)
    • Sub-heading within section 2 (h3)
      • Minor heading relevant to this sub-section (h4)

Learn to lint for issues

Mistakes with heading levels are easy to make, especially if you are working with a component-driven system like React. I'd strongly encourage you add a linting extension to your browser to allow you to highlight any inconsistencies in your heading levels easily. My favourite is the Axe Chrome Extension, which analyzes your page with one click and clearly reports and highlights where heading levels have gone awry.

Think about heading flexibility when creating reusable components

If you work with a component-based framework like React, remember to avoid hard-coding heading levels, so that they can be set according to the context they appear in. I wrote a little bit about this here:

A final note for writers here on DEV

Did you know that DEV automatically creates an h1 element for your post, containing the title you gave it? this means if you'd like to keep DEV accessibility-friendly, your first heading in your markdown content should be an h2 - i.e. ## First heading inside post. From there, you can apply the same principles as detailed above to keep everything accessible!


Did you find this post useful? Please consider buying me a coffee so I can keep making content 🙂

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .