For accessibility purposes, you could think of headings as a table of contents. But what if there are headings without contents?
On a web page, a heading (h1
, h2
, h3
etc) signposts ‘a section about X starts here’. Heading names are section names, in that sense. If, in a banana bread recipe, one heading says ‘Ingredients’, and the other says ‘Method’, expectations are set about what can be found where. Under the first heading, we’ll expect what goes into the banana bread, under the second we’ll expect some steps to follow.
The issue
Now, a problem I saw on a website recently: headings with no content. The issue wasn’t empty hx
elements, it was that there was no content between these elements and the next. This can happen when the heading element was picked merely for its looks, rather than as a way to indicate that there is some content—and what kind of content.
<h1>Banana bread</h1>
<h2>It's tasty</h2>
<!-- nothing -->
<h2>It's healthy</h2>
<!-- nothing -->
<h2>It can be anyway</h2>
On a site with beautiful heading styles, this could look great, but structurally it is unhelpful, because when someone navigates to one of these h2
’s, they find nothing.
It could also constitute a failure of WCAG 1.3.1: Info and relationships, because you’re basically claiming a structural relationship when there isn’t one.
So, the two questions to ask for headings:
- useful description: does this clearly say what kind of content I can find underneath?
- content: is there any content available underneath?
In the example above, only the h1
meets the criterion of being something we would want to navigate to. The bits underneath are more of a list of unique selling points. Something like this would be better in this context:
<h1>Banana bread</h1>
<ul>
<li>It's tasty</li>
<li>It's healthy</li>
</ul>
Note: the problem is not multiple headings as such, it’s multiple headings of the same level, that have no non heading content that they are a description for.
In summary
When you use a heading element, you set the expectation of content—always have content between headings of the same level.
Thanks to Jules Ernst, who explained this problem to me first.
Update 8 September 2020: added nuance to whether this fails 1.3.1
Comments & mentions (67)
The reason this happens is that many developers look on the hN heading elements as a means to set font size. These elements aren’t intended for display purposes (though browsers use them for that), they are there to indicate the document structure to screen readers and other assistive technology.
There was a proposed HTML5 element to deal with this, but it was removed from spec long ago.
Given that the outline algorithm proposed in HTML5 is ignored by every major browser, it’s just as well.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hgroup
http://html5doctor.com/computer-says-no-to-html5-document-outline/