Headings describe sections of the page and are designed to convey a logical hierarchy. If structured correctly they allow users to better understand the organization of the page. They are specially important for screen reader users. Have you tried accessing content with a screen reader using only the
tab key? It’s not a fun experience. Headings let you navigate the page using them as shortcuts, giving you easier access to the content.
1.3.1 - info and relationships of the WCAG 2.1 guidelines states that relationships and information should be communicated to everyone not just visually. For example a
div that you style to look as a heading will be bold, and the font size bigger than the body text. Its meaning will be implied by visual cues so a user that can see the page will understand that it’s a heading and associate it with the content bellow. A screen reader user who lacks vision on the other hand can’t make that association because a
div does not have semantic meaning. If it doesn’t have semantic meaning that section of the page will be skipped by someone navigating the page using headings as a shortcut. In other words, if you are labeling a section of the page use a heading, not a
span or paragraph.
Headings using ARIA
ARIA stands for Accessible Rich Internet Applications and consists of a set attributes that help make web content more accessible. Through the use of roles, states and properties it allows us to provide semantics in cases where native html can’t be used or you are building a custom widget for which html has no element. Note that the use of native html is always preferred and a recommended best practice, the first rule of ARIA says so itself.
If you can use a native HTML element or attribute with the semantics and behavior you require already built in, instead of re-purposing an element and adding an ARIA role, state or property to make it accessible, then do so.
First of all, please don’t. Second, do you really have to? like really. If you do ever find yourself in a situation where a heading can’t be used though, a
aria-level attribute will help assitive technologies identify it as a heading. Where
aria-level is used to indicate the hierarchy level:
<div role="heading" aria-level="1">I'm pretending to be an h1</div> <div role="heading" aria-level="2">I'm pretending to be an h2</div> <div role="heading" aria-level="3">I'm pretending to be an h3</div>
Don’t skip heading levels
Though technically not a failure of a WCAG success criterion, following a logical heading hierarchy is considered a best practice. Specially for users who can’t see the page as it helps them understand the relative importance of different sections.
It’s recommended to use one
h1 in your page and nest
h6 in sequential order. Starting the page with an
h2 is also valid if conforming to WCAG level AA.
Headings should describe the content bellow them
If text that relates to the heading is above it, it will be skipped by blind screen reader users who navigate the page using headings. A common example of this is when creating a card, or a blog post with meta information about the author or date:
<article> <time>July 15, 2020</time> <h2><a href="">Why Red dead redemption 2 is overrated</a></h2> <article>
Instead do this:
<article> <h2><a href="">Why Red dead redemption 2 is overrated</a></h2> <time>July 15, 2020</time> <article>
- Don’t use divs or spans to describe sections of the page, they have no semantic meaning, use a heading.
- If you absolutely can’t use semantic markup for whatever reason, use ARIA.
- Don’t skip heading levels.
- Content related to a heading should be bellow it.