Heading headache

I found a bit of code on a site that befuddled me. I could hardly believe what I read. I showed it to others in the accessibility community and they were as astonished as I was. We were all chuckling. The snippet of code was indeed a doozy. But some developer wrote it. He thought it was the right thing to do. Let’s look at this snippet and explain why it doesn’t work.

The offending snippet

<h2 class="h3" role="heading" aria-level="1">Some heading</h2>

Why are accessibility specialists rolling their eyes at this? Because the code undermines what the heading tag does. But let’s pull this one apart a bit more.

Headings – A quick recap

Screenshot showing the Rotor This is what a heading list looks like in VoiceOver

Taking the snippet apart

Using a class

There’s nothing wrong with assigning headings classes. There are plenty of uses for that. In this case, however, the class is h3 yet the heading level is 2. The assumption here is that they wanted to style h2 to look like h3. This is a problem because of the impact it has on sighted users relying on headings to understand the page’s hierarchy.

Using a role

There’s nothing wrong with assigning roles to HTML elements. An added role should not change the semantic meaning of an HTML element. Here it’s fine because the role is “heading”, and the element is a heading. In fact, it is redundant to use the heading role on a heading tag. But it doesn’t hurt.

The problem is that the attribute aria-level was used to define a different heading level than the tag’s. And it’s a bad idea to change the nature of a tag. If you want a h1, then use a h1. If you use an h2, then don’t try to force it to behave like a h1.

Keep it simple

Use existing HTML tags whenever possible. Don’t try and make them behave differently than what they are supposed to. Keep it simple, eh?

Here’s what it could have looked like:

<h2 class="display1">Some heading</h2>