DEV Community


Getting Heading Levels Right - Including Here on DEV

s_aitchison profile image Suzanne Aitchison (she/her) Updated on ・4 min read

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 🙂

Discussion (9)

Editor guide
s_aitchison profile image
Suzanne Aitchison (she/her) Author

There was a really great post on this recently that I recommend:

Also you might find this page useful on my website Up Your A11y: Accessible Page Layouts

Adding a lint tool like Axe or Wave to your usual development browser and checking in with it regularly will give you lots of great pointers too.

Hope this helps!

s_aitchison profile image
Suzanne Aitchison (she/her) Author

I should also say, regardless of which HTML element your header is in, you can and should always consider it in connection with all other headers on the page - in terms of heading hierarchy you consider the page as a whole. Again, it helps a screen reader user scan the content the same way a sighted user would.

Using those additional semantic elements give your page other accessibility boosts, so definitely keep using them too!

rhymes profile image

Great article Suzanne, maybe we should change the markdown parser of the article editor to be smarter and disallow h1s...

s_aitchison profile image
Suzanne Aitchison (she/her) Author

Maybe it would be good even just in the guidance/"Things to know" page if we included some pointers 🤔

rhymes profile image

The editor guide is a possible place to put this but I feel having an automatism would make sense also for people that don't read it, or if the article gets in from other avenues (like RSS feeds and the API).

Would you consider opening an issue about this?

timrodz profile image
Juan Alejandro Morais

So much yes! What a great post, Suzanne - thanks for sharing your experiences!

s_aitchison profile image
Suzanne Aitchison (she/her) Author

Yes sorry I realised that after I posted - woops! Hopefully my other reply makes sense 🙃