Working on WordPress core, themes, and in plug-ins, I find myself in frequent discussions about appropriate hierarchical structures for headings.

Headings hierarchies have to do with content relationships and structure, so unless you know everything about the structure of a specific page, it’s pretty hard to know what to choose. It’s not really possible for any independent piece of the front-end to set a perfect hierarchy — whether that’s coming from a plug-in, a theme, or from WordPress core.

Headings are important. They are the first step most screen reader users take when they begin to navigate your web page. 65.5% of users will start by navigating headings.. Solving this problem is worth tackling.

What are the problems?

In a content management system, where the rendered web page is constituted of parts coming from core functions, themes, and plug-ins, establishing a logical hierarchy is tough. These independent pieces of the puzzle don’t know what other pieces are doing. If core defines a heading for accessibility reasons as an H1, it provides a key structural piece for the site. But if the theme sets up the headings hierarchy using a single H1 model, where the site title is an H1 and all other parts descend from that, then this H1 is the wrong element.

If a plug-in describes an internally consistent hierarchy that starts from an H2, and is intended for use in a post, but the theme uses an H2 for post titles, that’s not going to be the right headings hierarchy either.

Ultimately, headings hierarchies are up to site implementation more than they are up to any independent piece of that site. But even in that context, pinning down a logical heading hierarchy isn’t easy.

The Basics of Headings Hierarchy

Test your Hierarchy

For testing, I use the HeadingsMap AddOn for Firefox. It’ll show the headings interpreted either in a standard fashion or in the experimental HTML5 document ouline model.

Headings work the same way that an outline does. When following the tree, you can always stay at the same level, go down the tree one level, or go up the tree any number of levels. What you can’t do is go down the tree an arbitrary number of levels. So an h2 could reasonably be followed by any of an h1, h2 or h3, but not by an h4.

How do you organize heading hierarchies in a site?

Let’s start by describing some of the different philosophies about heading hierarchies.

The single H1

For a long time, it was considered cardinal that a page should only have one H1. This wasn’t part of the HTML (HyperText Markup Language) specification, but was considered to be significant for SEO and structural reasons. Under this model, a page should have only one H1, and all structures from that point forward should be H2 or lower. This is still a very common model.

Under this model, we have to ask which content should be wrapped in an H1. Most commonly, it’s the site title or logo, as the highest level block that all other parts of the page pertained to. This is simple, but it also means that the first heading on the page is redundant information, since the site title is usually contained in the title element.

Multiple H1 elements

Once we decide that a hierarchy can include multiple H1 elements, life gets a bit simpler – but we still need to decide which regions of the page should have headings.

If we assume that all headings must be visible, this is a big design problem. Add a heading to the sidebar? People don’t generally want to see a heading that just says “Sidebar”, or something to that effect. But if we allow headings to be visually hidden, then we can add a whole suite of structural headings labeling the major structures — header, content area, sidebars, footer — without interfering with our visuals.

Not everybody will agree with this methodology — because it doesn’t work well with the idea that headings should be ordered by something called “importance”. Personally, I hate referring to headings by something that I consider as unquantifiable as importance; but some might argue that the most important parts of any page are always the content — so using headings to mark up structure is a problem.

I think marking structure using headings is great, as long as you’re thorough and consistent.

Multiple H1 elements and HTML5 sections

Under HTML5, each semantic section (section, article, etc.) can have an independent heading structure. With this logic, every section can start with an H1, regardless of the parent section’s structure, and the HTML5 document outline algorithm will decide for the user agent what “virtual level” that heading should be used as.

It’s a brilliant idea — it resolves the need for authors who only create *part* of a document from having to know the headings hierarchy surrounding their work.

But it doesn’t work.

It just doesn’t exist in any practical way. Real world usage shows that no user agent has actually implemented this algorithm. And it won’t be a viable system until not just some users get it – but until all users get it, because headings structure has a deep and fundamental effect on the experience that users of assistive technology have with your site. (Not to mention complicated design issues in the CSS (Cascading Style Sheets) to tackle chains of nested headings.)

So, good idea, but it doesn’t work — and probably won’t for a long time, if ever.

ARIA landmark roles and HTML5 landmarks

There is, of course, a method of shaping the structure of a web page without any use of headings at all — using landmark roles from the ARIA (Accessible Rich Internet Application) specifications or using the HTML5 content wrappers that map to them. And these are absolutely things that you should use in every site or theme you build, because they have great potential for future use — and unlike the HTML5 document outline, without immediate negative repercussions.

But as a replacement for a good headings hierarchy, they aren’t a candidate. Document landmark regions are best used with labels, either with aria-labelledby or aria-label:

Using aria-labelledby

<nav role="navigation" aria-labelledby="primary">
    <h1 id="primary">Primary Navigation</h1>
    <ul>...</ul>
</nav>

Using aria-label

<nav role="navigation" aria-label="Primary Navigation">
    <ul>...</ul>
</nav>

Either case is valid, and in the first case, the label wouldn’t even need to be a heading. The structure would still be present. This is a great long-term future idea; but at the moment, support is not sufficient to depend on it, and user awareness of the option is still insufficient. Survey data shows that users of assistive technology usually start their search process by navigating headings — 65.6% of respondents to WebAIM’s fifth screen reader survey (2014) stated that this was their first step in navigating a long web page. Landmark roles, while increasing in awareness, was only the first step for a measly 2.8% of respondents.

While purely structural headings can be omitted entirely with ARIA roles, this creates a significant usability problem for a large percentage of users. Not cool.

What do I recommend?

Either the single H1 model or the multiple H1 model are fine — the most important key is to use headings; and after that the next issue is to try and maintain an internal hierarchy that’s consistent. Use ARIA landmark roles, as well, so that your page has an explicit semantic structure, but don’t depend on them.

Always remember that there’s a huge value to hidden heading elements that are primarily in place to provide structure. Having a specific top level heading for your section wrapper can make it much easier to manage the whole hierarchy.

If you want to look at what I’ve actually done, check out Universal, my accessible theme framework. (You can also find it on GitHub.)

Handling Headings in WordPress

For theme developers, you need to come up with a logical hierarchy that you like and stick to it. Whether a single H1 or multiple H1 elements, your theme should have an internal hierarchy that works – even though it’ll break the minute a user throws an H1 into post content.

For plug-in developers, this is a bigger problem. Ideally, you need to make your headings structure filterable, so that a theme or developer can specify where your plug-in’s hierarchy should start. But I haven’t done that with my plug-ins, I have to admit.

For content authors, you need to know the hierarchy of the theme you’re using, so that you know what headings you can and can’t use. (And you get a whole new network of problems if you switch to a theme with a different hierarchy.)

Ideally, themes could declare what heading level is their content’s top heading, and both plug-ins and the WordPress editor could pick up on that declaration to figure out which heading levels to use. Right now, you just have to know.