Accessible HTML5 heading structure in WordPress

How to get a WordPress developer all emotional and fanatic: discuss about heading structure.

Here’s my point of view on how headings should be set up in a WordPress theme. And an overview of the pros and cons brought up in discussions.

Semantic, meaningful headings in HTML5

One H1 to rule them all

  • One unique H1 per page, post or archive
  • Only on the homepage the H1 can contain the logo or the site title
  • On pages the H1 is the page title
  • On posts the H1 is the post title
  • On archives the H1 is the archive title

Use H2 through H6 in the content itself to give meaning to the structure of the content, like the index of a book. H2 for a paragraph, H3 for a sub-paragraph, etc. Don’t skip or mix up headings.

Best practice for the logo or the site title

  • On the homepage the logo or site title can be put into an H1. This is not a link, because that will be a link to the page itself.
  • The H1 can also be a (hidden) page title above the content, your choice.
  • On other pages the logo or site title is a link to the homepage and not an H1 .

Site description or tagline

The site description is no H2 because a heading should be followed by content of any sort (e.g. page content, widgets, navigation).

Sidebars

  • Give the sidebar a (hidden) meaningful H2 heading
  • Give the widgets inside the sidebar an H3 heading
  • Don’t use a H1, H2 or H3 inside a widget

Footer

  • Give the footer a (hidden) meaningful H2 heading
  • Give the footer widgets a H3 heading
  • Don’t use a H1, H2 or H3 inside a footer widget

Navigation

Give a navigation <nav> a meaningful heading, fitting the heading stucture of your theme. Like an H2 containing “Main navigation”.

HTML5 sections

Give HTML5 sections a meaningful semantic heading. Steve Faulker explains this in The HTML5 Document Outline.

Why is this structure important

People using a screen reader depend on headings to understand the structure of a site. What is the page about (H1), where is the navigation, what is important content and how is the content divided.
They can navigate a site using headings, quickly jump to a heading of interest. A heading “main navigation” or “sub menu” saves them a lot of time.

How can I see what the heading structure is like?

Use for example the Firefox Add-on Accessibility Evaluator. It adds a Accessibility menu to your browser with lots of useful info, one of them is “Headings”.

Heading menu

And this is what the heading structure of wordpress.org looks like:

Heading structure of wordpress.org

Homework: take your site and run it through the Accessibility Evaluator, now you can see how a screen reader user understands your web page. Does it tell a story about the structure of your page?

Discussion

“I only use H1’s, because in HTML5 you can”

When HTML5 came out, using a H1 for every section was a way of dividing your content. Super easy, no thinking needed.

Don’t use only H1’s: screen reader users get lost. What is important? How do I navigate, what is the structure? A sighted person can easily see how a page layout is build, a screen reader user has to listen and often guess. Did I mention Google is blind?

Sidebars and Footers

It’s hard to give a sidebar or footer a meaning full heading. The content may change per page or archive, and a heading like “Primary Sidebar” or “Complementary Content” doesn’t say much about the content. This is the hard part and I am open for suggestions on how to solve this.
One solution could be to give the content manager the option to also add a sidebar title when adding widgets in the Admin.

WCAG 2.0

If your site has to comply with WCAG, a meaningful heading structure is a must. In WCAG 2.0 it is allowed to skip headings, but the headings must be meaningful (descriptive).

The objective is to make section headings within Web content descriptive. Descriptive headings and titles work together to give users an overview of the content and its organization. Descriptive headings identify sections of the content in relation both to the Web page as a whole and to other sections of the same Web page.

More on WCAG 2 and headings:

SEO

Theme builders want their HTML optimized for Google. Google needs to be told what is important or not.

Now this is a point of much debate. What does Google need? How much weight should I give a widget or a subtitle? In the Genesis Framework all widgets have an H4, telling Google: this content is not very important.

Giving all pages the same first H1 using the site title and then  give the site description an H2, as most WordPress themes do, is to my opinion bad practice. Even if you change the title in your SEO options. But I’m no SEO expert, if you are: please give me your opinion.

So: who do you build for? For your sighted users and for the search engines? Be honest now. Do accessibility rules conflict with SEO best practice? And how complicated will your code get if you want to address all people, also the ones that depend on their ears to understand your site.

Manga art in the featured image by Suuzan on deviantART.

32 comments

  1. “I only use H1′s, because in HTML5 you can”

    The HTML5 Recommendation states:
    “Warning! There are currently no known implementations of the outline algorithm in graphical browsers or assistive technology user agents, although the algorithm is implemented in other software such as conformance checkers. Therefore the outline algorithm cannot be relied upon to convey document structure to users. Authors are advised to use heading rank (h1-h6) to convey document structure.”
    http://www.w3.org/TR/html/sections.html#outlines

    for implementation outlook refer bug links here https://www.w3.org/wiki/HTML/Usage/Headings/h1only#Notes

    further advice:
    https://www.w3.org/wiki/HTML/Usage/Headings/h1only
    https://www.w3.org/wiki/HTML/Usage/Headings/Missing

  2. Based on the CSS in many themes I think part of the aversion to changing the post title tag between index pages and single pages is that many developers use the h1/h2 declaration to style these elements instead of a CSS class. This would naturally cause style differences between indexes and single posts/pages.

    Not an excuse, but a possible reason.

    On that note I’m considering changing the tag structure of Simone to this approach. I used to do things the way you recommend here but abandoned it because _s abandoned it. Now I want to go back in the archive and look at when that happened and for what reason.

      1. I’ve had the same thought for a long time. I’ve even got a bug report in really rough draft form. It seems it’s time to revisit that. Headings have been a oft-raised-and-dismissed issue in _s.

  3. From an SEO perspective (I worked in SEO for a long time, and still follow best practices in that realm), the best practice for headings is that while the hierarchy doesn’t particularly matter, it’s preferable to have just one H1, and for that H1 to represent the most specific topic for that page – generally, that would be the post title. For hierarchy purposes, that makes it difficult to define a consistent heading structure for the surrounding characteristics, obviously.

    FYI, I wrote a similar article just a week ago, although from a different perspective: The Headings Hierarchy Challenge

      1. I’m trying to implement your suggestions with one H1/page idea and have a practical question.

        As you suggested, I marked Main Menu that is located in header with H2. But if visiting individual article, the outline of the document is this: https://cloudup.com/ctdWf4iUfVd

        Question: is it possible to have H2 at the top? If not, what would be the plan, to remove H2 heading from the Main Menu?

        Thank you!

        1. Hi Tomas,

          Great work!

          If it is allowed to have an H2 on the top depends on the guidelines you are following.
          For WCAG 2 AA it’s allowed, for the Dutch Government Accessibility Guidelines it’s not.
          For getting the accessibility-ready tag it’s also allowed.

          For practical accessibility (screen reader users) it’s fine, and it’s doesn’t hinder SEO imho.
          And it’s a hell of a job to alter this construction in WordPress.

          A good construction could be (copying your code):
          <nav id=”site-navigation” class=”main-navigation” role=”navigation” aria-labelledby=”primary-menu” itemscope=”” itemtype=”http://schema.org/SiteNavigationElement”>
          <h2 class=”screen-reader-text” id=”primary-menu”>Main Menu</h2>
          etc..

          Then you link the heading to the nav.

          I looked at your outline, and only the "about" and "leave a reply" H3's are not perfect, but that's a WordPress issue (altering headings in WP itself is an ongoing battle).

          A validator is a machine, so look at the results and decide what you want to alter yourself. We code for users, not for machines 😉

          Can you notify me when the accessibility changes are ready? I would love to make some noise for you.

      2. About the more than one H1: This is where Joe and I disagree. (As Accessible Joe always says: put 3 accessibility people in a room and you get 5 different opinions).

      3. Thank you, Rian, for thorough review! I investigated the use of aria-labelledby and it looks that in my case aria-label fits better, because the heading is hidden:

        “The aria-label attribute is used to define a string that labels the current element. Use it in cases where a text label is not visible on the screen. (If there is visible text labeling the element, use aria-labelledby instead.)”

        I’ll let you know when Tiny Framework theme will be approved for WP.org repository, thank you!

      4. I need some help on aria-label when used for hidden headings. Does the aria-label get ‘rendered’ by AT when the element is set to display: hidden ? Or do you use aria-label on a wrapper?

      5. Oh, sorry, one more question (I forgot). If I use the ‘one H1 per page’ rule, how does this work for ATs when the site navigation’s H2 is situated above the article title’s H1? (and the sidebar’s H2 on the same level as (or below) the H1 of the article). Strictly speaking isn’t it so that any site-wide stuff on a page (like navigation and sidebars) are unrelated to the content’s outline? We have at minimum 2, at maximum 3 outlines on a page:
        1. Page layout (header, navigation, content, footer)
        2. Content outline (e.g. headings in an article)
        3. (in collection pages, like archives) outlines for individual items (not just article excerpts but also widgets and apps)
        A web-page is not an actual physical page, in theory a webpage could contain multiple ‘virtual pages’ each completely unrelated to each other, so each should have its own top-level heading (where title-tag is the overall collection heading). Or am I overthinking it?
        This is so confusing.

  4. Hi,

    I’d like to improve accessibility of my themes and I’ve actually used the approach described in this article before but switched to _s way (similar story to mor10’s).

    However, I feel there is an issue with the rule “first heading tag on the website should be H1” here. That rule is basically broken on all the pages (except front/home page), posts and archives (at least in vast majority of cases).

    Also, I would like to ask if anybody have some insight about whether there is a difference in how screen readers outline the HTML document and how the browser does it? I use HTML5 Outliner tool in Chrome to check things up and I am quite satisfied with the output on my theme (at least the one I’m building right now). Does this HTML5 outline differs from what screen readers “see”?

    Thanks!

    Regards,

    Oliver

    1. Hi Oliver,

      the rule “first heading on the website should be H1”

      Looking at this from an accessibility point of view:

      For WordPress we want to comply with WCAG 2 AA rules, because these are globally the most used guidelines.
      And having the first heading an H1 is not a WCAG 2 AA rule.
      In the header of a WordPress site, H2’s are added to label the skip links, navigation and widget area, which is very useful for screen readers. The H1 is added on the homepage in the header, and for the rest of the pages just above the content.
      There is no a11y problem with this structure, for screen reader users the first heading doesn’t need to be an H1. More important is to have one H1 per page and the rest meaningful and semantically used.

      Not all screen readers support reading an outline, it depends on brand and version, the same for browsers. But screen reader users depend heavily on heading structure to navigate.
      And then there is this post by Steve Faulkner: The HTML5 Document Outline:

      If you as a developer want to provide a meaningful document structure, use the h1–h6 elements to express document structure. DO NOT rely upon the HTML5 document outline.

      Hope this helps
      Rian

      1. Hi Rian,

        Thank you for the reply and explanation. It really seems better solution for accessible websites. I’ll try my best to implement the proposed heading structure then.

        Regards,

        Oliver

  5. Hi Oliver,
    For WCAG 2 AA it is not required to have the H1 as first heading.
    I know the accessibility-tag rules states different and I don’t agree with that. This is being discussed in the wpa11y group at the moment.
    If you have problems getting the accessibility-ready tag because of this rule, please contact me.

  6. Hi Rian,

    Thank you very much for the answer. I am currently building a commercial theme, so this one won’t be listed in WPORG repository and thus I will keep the heading structure like it is now, according to your suggestions above.

    But I’d like to make it WP accessibility-tag compliant anyway as I would like to make all my themes accessible from now on. And obviously I’ve got very confused about the requirements the WordPress has. I needed some clarification for my future WPORG themes too.

    Thank you again and let’s hope this requirement will change to recommendation at least.

    Regards,

    Oliver

    1. Hi Oliver,

      FYI:
      The rule “First heading element on the page is not an H1” has been removed from the accessibility-tag requirements as from today 🙂

      Kind regards
      Rian Rietveld

      1. 🙂 This is a great news! Thank you! I’m glad I’ve asked you about this 😉

Comments are closed.