Menu

Heading structures are tables of contents

Published on by Hidde de Vries in code .

The heading structure of a web page is like its table of contents. It gives people who can’t see your page a way to navigate it without reading everything.

To be clear, by ‘heading structure’ in this post, I mean the heading elements in your HTML: <h1> to <h6>. These elements can be strongly intertwined with what they look like, but for our purposes it is the markup that matters.

The best analogy I’ve been able to come up with for heading structures, is the feature in Microsoft Word that lets users generate a table of contents automatically. It is used a lot by all kinds of people, in all kinds of environments (in long corporate documents, but also in academia). If you’ve set document headings correctly, it lists all sections and subsections. It even remembers, and updates, which page they are on.

Screenshot of Pages application with table of content settings open Example of the automagic table of contents feature in Pages. It even lets you select which heading levels to include!

All websites have this too, as a similar feature is built into most screenreaders. In VoiceOver, for example, users can press a button to see a list of all headings and use this to navigate a page. In fact, this is a common way for screenreader users to get around your page without reading everything.

Wikipedia page about assistive technologies with voiceover rotor headings open The headings feature in action on Wikipedia. Note that Wikipedia also lists the headings explicitly, with section numbering.

Only use headings to identify sections

To let users get the best navigate-by-headings experience, only use heading elements for content that actually identifies a section. Ask ‘would this be useful in my table of contents?’, and if the answer is no, best choose a different HTML element. This way, only table of contents material makes it into your heading structure.

For this reason, by the way, I recommend to avoid having headings be part of user generated content (as in: content added not by content specialist, but by users of your site). If you offer Markdown for comments, for example, headings in those comments could mess with the usability of your heading structure.

If you choose something to be a header, make sure it describes the section underneath it. This can be hard to get right, you might have great puns in your headings, or maybe they were written by a SEO expert.

Visually hidden headings

Not all sections have headings, often the visual design makes it clear that something is a distinct piece of content. That’s great, but it doesn’t have to stop a section from also showing up in your table of contents. Hidden headings to the rescue!

A hidden heading is one that is ‘visually hidden’, this is content that is not visual on screen, but it exists in your markup and screenreaders can use it:

<h2 class="visually-hidden">Contact information</h2>
<!-- some content that looks visually a lot like contact
     information, with icons and a receptionist stock
     photo that makes it all very obvious-->

(More about CSS to visually hide)

The heading goes into your virtual table of contents, but it is not visible on screen.

Note that visible headings are much preferred to hidden headings. There are two problems in particular with hidden headings:

‘Don’t skip heading levels’

Although WCAG 2 does not explicitly forbid skipping heading levels, and this is controversial, I would say it is best not to skip heading levels.

If a contract has clause 2.4.2, it would be weird for there not to be a 2.4 — the former is a subclause of the latter. It would be weird for the subclause to exist without the main clause.

The most common reason why people skip headings is for styling purposes: they want the style that comes with a certain heading and that happens to be the wrong level for structural purposes. There are two strategies to avoid this:

The former is what I prefer, on many levels, but if it is a choice between weird CSS and happy users, that’s an easy one to make.

Automatically correct headings

The outline algorithm mentioned in HTML specifications is a clever idea in theory. It would let you use any headings you’d like within a section of content; the browser would take care of assigning the correct levels. Browsers would determine these levels by looking at ‘sectioning elements’. A sectioning element would open a new section, browsers would assume sections in sections to be subsections, and headings within them lower level headings.

There is no browser implementing the outline algorithm in a way that the above works. One could theoretically have automated heading levels with clever React components. I like that idea, although I would hesitate adding it into my codebases. That leaves us with manually choosing plain old headings level, from 1 to 6.

Conclusion

Heading structures give screenreader users and others a table of contents for our sites. By being conscious of that, we can make better choices about heading levels and their contents.

Thanks Matijs and Léonie for their great feedback on earlier drafts of this post.

Comments & mentions (34)

Comandeer replied: hiddedevries.nl/en/blog/2018-0…
Michael Hastrich reposted this
Jasha reposted this
Michael Hastrich likes this
Kev likes this
Scott O'Hara reposted this
jameschurchman likes this
@timsev@mastodon.social replied: RT @Hdv@toot.cafe
✏️ Heading structures are tables of contents hiddedevries.nl/en/blog/2018-0…
toot.cafe/@Hdv/100657475…
Gaël Poupard likes this
Accessabilly likes this
Jon Gibbins likes this
@baldur@toot.cafe replied: “Heading structures are tables of contents” hiddedevries.nl/en/blog/2018-0…
reposted this
likes this
Deborah Edwards-Onoro replied: Heading structures are tables of contents hiddedevries.nl/en/blog/2018-0… #HTML #a11y
Jon Gibbins reposted this
=accessibility reposted this
krista sarginson likes this
Marco Zehe reposted this
KseniaBlake likes this
Johan Ramon replied: Heading structures are tables of contents: hiddedevries.nl/en/blog/2018-0…
#accessibility #a11y
Web Axe replied: "Heading structures are tables of contents "—the why and how to implement hiddedevries.nl/en/blog/2018-0… by @hdv #webdev #a11y
Web Axe replied: "Heading structures are tables of contents "—the why and how to implement hiddedevries.nl/en/blog/2018-0… by @hdv #webdev #a11y
Bʀᴇᴛᴛ Jᴀɴᴋᴏʀᴅ likes this
Masao YOMODA replied: Memo.
>Conclusion
>Heading structures give screenreader users and others a table of contents for our sites. By being conscious of that, we can make better choices about heading levels and their contents.
hiddedevries.nl/en/blog/2018-0…
Sara likes this
Damion Armentrout reposted this
Damion Armentrout likes this
Benno Löwenberg replied: #accessibility & #usability are determined by the shape of the buidling blocks that serve as foundation for #interaction too:

Instead of looking at whole pages only, can #PatternLibraries already be tested for #A11y & how? — by @hdv :

buff.ly/2vZRjuK

#DesignSystems
Benno Löwenberg replied: #accessibility & #usability are determined by the shape of the buidling blocks that serve as foundation for #interaction too:

Instead of looking at whole pages only, can #PatternLibraries already be tested for #A11y & how? — by @hdv :

buff.ly/2vZRjuK

#DesignSystems
John F Croston III likes this
Peter Armstrong reposted this
Brian J. Perdue reposted this
GravityDrive replied: The heading structure of a web page is like its table of contents. It gives people who can’t see your page a way to navigate it without reading everything.
hiddedevries.nl/en/blog/2018-0…
Leave a comment
Posted a response to this?

This website uses Webmentions. You can manually notify me if you have posted a response, by entering the URL below.