Headings in HTML 5 and accessibility
Firstly, apologies for the much-delayed second round of my HTML 5 redesign. Two things delay it:
- Understanding the precise relationship between the
article
,section
,header
,nav
andfooter
elements. What each element is for is relatively easy; how each element interacts is another. Fortunately, I work with Lachy and Anne who were able to help me. - Styling the stuff cross-browser. CSS is always a slow process for me, especially with “new” elements.
This description of headings was originally part of a post unveiling the part two redesign, but I’m splitting it out because there has been a lot of talk lately about headings in HTML 4 and 5. The redesign will be unveiled after my trip to Oslo next week.
Headings in HTML4
We all know these; there are six layers, h1
to h6
. If you want more levels, you’re stuffed. There are arguments that more than six levels is somehow confusing; I think that’s an empty argument. Badly structured content is confusing, even if it has only two levels of heading. Conversely, some well-structured content might legitimately more levels and the language doesn’t allow for that.
Headings are very useful for search engines; it helps them “understand” content. They are also vital for screenreader users who can navigate via headings. In JAWS, for example, a user can hit H to go to the next heading, 1 to go to the next h1
, 2 to go to the next h2
and so on. I thoroughly recommend watching Importance of HTML Headings for Accessibility, a video by a blind web developer who shows how screenreader users navigate using headings.
Opinions are divided about whether accessibility is better served by never having more than one h1
per page, whether “skipping” a level (from h2
to h4
with no intervening h3
, for example) for consistency’s sake helps or hinders are all arguments that Henny Swan excellently summarises, so please comment there on those questions.
The problem with “hardcoded” headings is that they are hardcoded and can’t change according to context. The title of this whole blog post is presented by WordPress as a h2
on the home page, but as an h3
on a category page (as there is an h2
there saying “all posts in the HTML 5 category"). But the internal headings aren’t controlled by WordPress; I’m hardcoding them as h3
. Unfortunately, they therefore remain at that level on the category pages, thereby destroying the hierarchy of headings.
Headings in XHTML 2
XHTML 2 has an elegant solution to this problem, and proposes an all-purpose h
element as a general purpose heading. It gets its position in the hierarchy from how many levels of section
elements wrap it.
Structured headings use the single h element, in combination with the section element to indicate the structure of the document, and the nesting of the sections indicates the importance of the heading. The heading for the section is the one that is a child of the section element.
So <body><section><h>Heading</h></section>
is the same as an h1
, and styleable with a CSS
rule like section h {color:red;}
.
<body><section><section><h>Heading</h></section></section>
is the same as an h2
, and styleable with a CSS
rule like section section h {color:green;}
.
Content Management systems can therefore take a lump of content (like this article) and wrap it in a section
element and change the level of all the headings.
Headings in HTML 5
HTML 5 attempts to be backwards compatible, so it uses XHTML 2’s section
element with the numbered headings from HTML 4 so that legacy content still works. That means that determining the “level” of any header is dependant on its explicit number (is it h1
or h-something else?) and how many levels of section
surround it.
The algorithm is complex but tightly defined. My section
demo page gives an idea of how this works, as well as styling examples. James Graham has written an outlining tool and I expect that tools such as Opera Dragonfly and Firebug will provide methods to work out "computed" levels of heading.
So in my redesign, I’m wrapping each article in a section
element on a "category" page so that the hard-coded h3
s ‘turn into’ h4
s, which is a fine and dandy way to deal with this legacy content.
Accessibility
Current browsers don’t magically rejig the levels of headings, of course, as they have no knowledge of the section
element, so just read that heading as the hard-coded h3
. Those using screenreaders are not worse off and I’m future-proofing the document.
But the HTML 5 spec discourages mixing heading levels and sections:
Sections may contain headers of any rank, but authors are strongly encouraged to either use only h1 elements, or to use elements of the appropriate rank for the section’s nesting level.
Authors are also encouraged to explicitly wrap sections in elements of sectioning content, instead of relying on the implicit sections generated by having multiple heading in one element of sectioning content.
(This “discouraging” in a spec seems to me a disingenuous way of indicating that there is a kind of “HTML 5 transitional” spec wrapped up in the main spec. The code structures that are "discouraged" are very useful for transitioning legacy content, and the spec should say so in my opinion rather than daintily "discouraging".)
This says that authors of new content should really only use h1
for headings, and when they want sub-headings should do so by making another section
. That’s all well and good, but what about screenreaders?
Current screenreaders would just see every heading on the page as a hard-coded h1
, which destroys the ability to get a conceptual framework of the page or navigate it. In order to take advantage of the new HTML 5 way of computing the relative level of headings, screenreaders would need to incorporate the outlining algorithm. This isn’t too much to ask; they are user agents that consume and transform web content; the algorithm is open and published.
Let me put my cards on the table: if you correctly use a W3C specification, like this one, and obey WCAG, then I believe that your responsibility as a web author is done. I won’t delay using a technique because a user agent can’t deal with it (although I will try to give extra help where I can). Call me evil, but that’s how I feel today.
I’ve been worried enough to ask the HTML 5 top nobs to explicitly invite the main screenreader vendors to participate in the the development of the HTML 5 spec. Unfortunately, to my knowledge, we’ve seen no interest from them. Perhaps they don’t think their customers are interested; after all, they don’t even alert their users to HTML 4 elements like strong
, em
, b
, i
or del
.
(Last Updated on )
Buy "Calling For The Moon", my debut album of songs I wrote while living in Thailand, India, Turkey. (Only £2, on Bandcamp.)
20 Responses to “ Headings in HTML 5 and accessibility ”
Ditto what Tom’s saying – multiple h1 can screw up pages for people who rely on headings to navigate. A single, unique h1 on each page seems like the safest option for me.
Are there many web pages that require multiple h1 headings?
Hey Bruce,
Really enjoying these HTML 5 articles – they’ve prompted me to venture on to the new standard, and help with coming to grips with the huge spec document over at w3c.
Got a comment about the use of tags in HTML 5 – wouldn’t it be great if you could use either or ? Then you could have a new HTML5 compliant document with only elements (and ranking is properly sorted by section), or a transitional HTML4/5 document using .
A lot of people use a H1 tag for the logo and then add another h1 for the main heading tag.
There’s a whole debate going on: http://www.h1debate.com
I prefer to have only one H1 per page.
@Daniel: that http://www.h1debate.com site obviously isn’t interested into accessibilty much, making the tweeted texts almost unreadable. Or they are only interesting in a number, not in the reasoning behind people’s usage. Personally I think it makes no semantic sense to have two H1 headers right after each other. But level numbering is arbitrary, as long as you’re consistent there shouldn’t be problems for your users.
@Rijk I am the designer of the H1 Debate, and wanted to emphasise the poll first and the comments second, hence setting the opacity at 50%. If you hover over a tweet, it’s opacity increases to 100%.
Although the poll numbers are important, the comments make are the key to the debate. Each tweet is a vote after all, and I have had some great feedback from some of the Webs’ most respected designers.
As the HTML 5 spec clarifies, it’s perfectly OK to use, say, a h2 as first-level title of its own section. Since there’s no h1, the outline algorithm will treat it as a first-level header. Yet, in “section”-unaware devices, the whole page structure will stay consistent and understandable.
So this approach is perfect for everyone, except the light frustration one can have as an author to type an h2 without prior h1 (although this is semantically unambiguous, as I just mentioned). I personally think I’ll be able to deal with this frustration, and this approach is a nice way to combine semantically correct code and consideration to HTML 5 unaware devices.
At this point, it’s also important to take into account that e.g. Braille readers are pretty expensive. Moreover, as you pointed out, some vendors are not very responsive, so maybe they won’t release compliant devices anytime soon. Let’s change our first-level (in a given section) h2’s to h1’s later, whenever everyone’s ready, it won’t be a lot of work anyway.
[…] they apply to as child elements (XHTML2 was proposing that and HTML5 has it to a degree – Bruce Lawson write a nice post about this and there’s also a pretty nifty HTML5 outliner […]
“from h2 to h3 with no intervening h4, for example”
Shome mishtake? I think you mean:
“from h2 to h4 with no intervening h3, for example”.
[…] Headings in HTML 5 and accessibility […]
[…] less ideal solution for web-hosted-app development, it’s actually a blessing in disguise. HTML5 is a highly accessible web standard, which can be scaled gracefully across multiple devices, and […]
[…] Bruce Lawson put it well more than a year and a half ago: […]
[…] page title, and not the site / company name. I’m still not sure I get how to use the revised heading order so I’m sticking with old school h1-h6 for […]
I’m already trying to use (almost) only h1s on Gastero Prod, and even created a stylesheet for multi level sectioned h1 styles. The (obvious) name is HTML5-Titles-Inception, and freely available/forkable on Github…
[…] the page title, and not the site / company name. I’m still not sure I get how to use the revised heading order so I’m sticking with old schoolh1-h6 for […]
[…] redesigned site using HTML5. In particular read about how headings and sections work together in HTML5, headings and accessibility. I’ll also be following up this post with looking into accessibility issues around HTML 5 and […]
[…] page title, and not the site / company name. I’m still not sure I get how to use the revised heading order so I’m sticking with old school h1-h6 for […]
[…] Headings in HTML 5 and accessibility […]
A few months ago I was at accessibility seminar where a blind user demo’ing a few sites and sites with more than one H1 completely threw him, and sites with the website heading as H1 were of irrelevance.
So now I use the page title, in this instance ‘Headings in HTML 5 and accessibility’ as the only H1.
Sorry, I’m just streaming in the youtube video link you posted, so I may just be repeating what is said there 🙂