The harsh truth about HTML5’s structural semantics (part 2)

In the first part of this series we covered the failings that lead to HTML5’s structural elements, in this second part we’ll look in detail at the consequences of those failings.

I’ve said several times that HTML5 introduces a new method of structuring a web page, and you’re probably wondering what that actually is. It’s right there in the spec, which introduces the concept of ‘sectioning content’: sectioning content is content that defines the scope of headings and footers. Each sectioning content element potentially has a heading and an outline.

The spec documents its approach to headings, sections, and outlines to make the concept clear. Well, clear to those who have to implement the functionality in browsers. For us to understand HTML’s structural elements (section, article, nav, aside, and their related elements header and footer) and this obscure concept of ‘sectioning content’ or ‘outlining’, we need to take a little trip through HTML history.

 

Outlining an old concept

The concept of outlining introduced in HTML5 can be traced back as far as 1991 and was included in the ill-fated, dead-end XHTML 2.0 spec, and finally sees the light of day in HTML5… only to be so poorly communicated that the idea is pretty much dead on arrival.

Prior to HTML5, the hierarchical structure of a page was determined by the heading elements — our old friends h1 through to h6. We could structure a page by saying the page title is h1, the article heading may be h2, and perhaps subheadings in the article may be h3 and h4, and so on.

This is fine for a simple document, but using heading tags to create a logical hierarchy, or ‘document outline’, for a complex, modern web page is very difficult. Part of the problem is the lack of a way to determine where a page section starts and stops. For example, say we had our previously mentioned document with h1 for the page title, h2 for the article title, h3 for the subheadings, but then wanted to mark up the title for our sidebar sections with h3 headings as well.

The document outline such a structure would create would look something like this:

<h1>My Old Blog</h1>
      <h2>My Latest Blog Post</h2>
            <h3>My Blog Post Sub Heading</h3>
            <h3>My Blog Post Sub Heading</h3>
             <h3>About Me</h3>
             <h3>Archives</h3>
             <h3>Social Links</h3>

Here, the h3 elements are ‘owned’ by the h2 above them, even if it doesn’t make much sense. Of course, we would break these up with something like div for the article, and div for the sidebar, but these are ignored by user agents (such as screen readers) who determine the page outline by heading structure alone.

By tying page hierarchy directly to what are often presentational heading levels, we are limited in how we can structure a page.

 

A fresh attempt at an old target

In an attempt to solve this problem, HTML5 introduces the concept of ‘sectioning elements’, that is, special elements that divide the page up into — you guessed it — sections, and those sections determine the nesting level of headers, and indeed the hierarchy, or ‘outline’ of the page.

That is, the hierarchy of the page is uncoupled from the heading elements, and instead these new sectioning elements determine what level a heading element actually is.

In the first draft XHTML 2.0 specification, sectioning worked with a section element, and a generic header h element. When writing HTML, we then wouldn’t specify what level of heading we wanted to use, we’d simply let the browser determine the level of nesting for a given heading. We could nest section elements 99 levels deep, and an h element at the 99th level would be equivalent to an h99 element. This way, we can structure our documents logically, without worrying about how we can use the limited h1-h6 elements.

(This idea really does date back to 1991, by the way: as Jeremy Keith pointed out, Tim Berners-Lee mooted the idea of a section and h element to structure a page at the end of this October 1991 email.)

Hickson attempted to introduce this same concept into HTML5, but with an added degree of difficulty: he wanted to maintain backwards compatibility, and introduce some new semantics to ‘simplify authoring’ to boot. Therefore, instead of just having a section element in HTML5, we also have an article, nav, and aside element that all do the same thing as section, but with different names, to be used in different ways.

What does the spec say about these elements? I encourage you to read the spec for yourself, but here’s a taste:

<section>

The section element is the foundation of sectioning to create a document outline.

The section element represents a generic section of a document or application. A section, in this context, is a thematic grouping of content, typically with a heading.

Examples of sections would be chapters, the various tabbed pages in a tabbed dialog box, or the numbered sections of a thesis. A web site’s home page could be split into sections for an introduction, news items, and contact information.

A note in the spec says the element should not be used for purely styling purposes — a div would be better there, and understandably so, as sections thrown in willy-nilly for styling would create a very broken document outline.

The note goes on to say ‘A general rule is that the section element is appropriate only if the element’s contents would be listed explicitly in the document’s outline’ and that’s the clearest statement about the section element in the spec.

When we understand the concept of sectioning and outlining, the inclusion of the section element makes sense. It didn’t appear in the common class values research, but it did appear in XHTML 2.0, and dates back conceptually to 1991.

<article>

The other structural elements HTML5 introduces — the ones that were supposedly reflected in the research — do the exact same thing as the section element, as far as the document outline is concerned. They also create the hierarchy of the page, and thus the document outline.

Take the article element for example. Many people assume that it’s simply for articles like this one. But that’s not it at all. It’s ‘article’ in the sense of ‘an article of clothing’. It’s better thought of as ‘item’ as in ‘an item of clothing’, as its definition is that broad.

When article elements are nested, the inner article elements represent articles that are in principle related to the contents of the outer article. For instance, a blog entry on a site that accepts user-submitted comments could represent the comments as article elements nested within the article element for the blog entry.

In HTML5, user comments, the article proper, forum posts, and even ‘interactive widgets and gadgets’ are all articles. The definition is so broad as to be useless—semantics are supposed to impart meaning, but using a collective term for such a broad variety of items renders the element meaningless.

This is one example where we’ve forked the spec — a few people follow the spec correctly and make almost everything an article (blog post summaries, blog posts, comments, widgets, forum posts, etc.), while others have kept it only for the main article on a page, which is only one part of its broad definition. You may think it doesn’t matter either way, and to a large extent you would be right. But think about all those reading services that aim to just parse the main content of the page. Which implementation of the spec should they follow? Should they follow what the spec actually says, or should they follow the general community implementation where there’s usually just one canonical ‘article’ on a page?

This is a missed opportunity, and what happens when the specification fails to actually specify, and the editor and, to be fair, the community, fails to communicate what the spec actually says.

Imagine if article wasn’t also used for comments. Imagine if comments got their own element, for example, and adoption became widespread. Browser makers could add a ‘mute comments’ function that could easily hide (or otherwise parse) comments on web pages. But Hickson has specifically refused a request for a comment element. In HTML5, it’s articles all the way down.

<aside>

Aside is another element that doesn’t appear anywhere in Hickson’s class name research, and gets a very peculiar definition to boot:

The aside element represents a section of a page that consists of content that is tangentially related to the content around the aside element, and which could be considered separate from that content. Such sections are often represented as sidebars in printed typography.

The element can be used for typographical effects like pull quotes or sidebars, for advertising, for groups of nav elements, and for other content that is considered separate from the main content of the page.

Who knows why aside should cover both pull quotes, sidebars, advertising, and groups of navigation elements, but it also creates new sections in the document outline. This means pull quotes get their own bullet point in the document outline, which seems, let’s say, ‘odd’. Again, its haphazard use by well-intentioned web designers has and will create plenty of broken document outlines.

<nav>

The nav element seems the most self-explanatory of the sectioning elements, and thankfully the definition hasn’t been stretched beyond breaking.

The nav element represents a section of a page that links to other pages or to parts within the page: a section with navigation links.

Which is fine, and could have theoretical accessibility benefits (a user agent could skip past, or jump to, the nav links—they don’t, but they could).

The problem is that in the spirit of ‘simplifying authoring’ and replacing div with the nav element, we blow up the navigation styling for another subset of users. Users of IE6-8 with JavaScript off (Yahoo’s research suggests 1-2% of all users have JavaScript off) are victims of this problem. With JavaScript off, the JavaScript-based HTML5 shim that helps IE6-8 understand HTML5 elements doesn’t work, so the browser doesn’t style HTML5 elements. This may only affect a small number of users, but why affect them at all?

<header> & <footer>

The header and footer elements are a classic case of taking common terms and giving them very different uses.

The spec states that neither of these elements create new sections in the document outline, despite the fact they are often depicted as being on par with section, nav, article and aside. In fact, they don’t do anything at all. They’re just included to demarcate areas of a specific section in the document outline.

Here’s what the spec says about header: the header element represents a group of introductory or navigational aids.

Note: A header element is intended to usually contain the section’s heading (an h1–h6 element or an hgroup element), but this is not required. The header element can also be used to wrap a section’s table of contents, a search form, or any relevant logos.

and footer: the footer element represents a footer for its nearest ancestor sectioning content or sectioning root element. A footer typically contains information about its section such as who wrote it, links to related documents, copyright data, and the like.

In HTML5, the body element is actually the root section element, so an overall header and footer is intended to describe the root body section. Any section can have a header and/or a footer—they’re not intended just for overall headers and footers, as we may have assumed. Individual comments can each have a header and footer, for example. In fact, as we touched on earlier, the spec actually gives an example of footer being used in a comment above the actual comment content. That’s right, in HTML5 comments are articles, and they can have a footer for a header, and that’s in the actual specification. Did you want a footer element for the header of your comments? No? Well, you’ve got one.

Again, this is where HTML5 takes common terms, and uses them in ways that are unrecognizable to the common web author.

 

That’s sectioning, what’s missing?

But there’s something we haven’t looked at in HTML’s implementation of sectioning. Did you spot it? We have the sectioning elements, but we don’t have a generic h element. Not to worry, the solution is in the spec:

Sections may contain headings 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.

HTML5 wants to be backwards compatible, so the WHATWG decided not to introduce an h element (despite introducing a bunch of new sectioning elements), and instead wants to repurpose the h1 element to be the generic h element. Use h1 everywhere, and let the HTML5 outlining algorithm determine its true level… or so the theory goes.

This is a terrible idea for several reasons, the two main ones being accessibility and styling.

Accessibility

Using h1 everywhere is very bad for accessibility. Blind users rely heavily on the heading structure of a site. It’s important for all of us to be reminded of just how crucial heading structure is for accessibility purposes. For instance, a December 2008 survey of over 1000 screen reader users conducted by WebAIM found that 76% of blind and vision-impaired users ‘always or often’ navigated by headings when they were available. And a May 2012 survey found that 82.1% heading levels were ‘very useful’ or ‘somewhat useful’ when navigating a web page. (This is good, practical research, so take note.)

Having h1s everywhere will make sites harder to navigate for blind users. In theory, screen readers would use HTML’s outlining algorithm instead and navigate using the document outline, but given the way authors have been told to implement sectioning elements, outlining is a mess, and attempting to navigate document outlines which have been given no thought whatsoever would be even worse for blind users.

The HTML5 spec offers a way out: keep using the appropriate h1-h6 levels to maintain backwards compatibility. But now we’re maintaining two document outlines in the one document, and given the problems authors have had in even considering the document outline in the first place, the likelihood of anyone maintaining both a logical h1-h6 outline, and a logical, properly-sectioned HTML5 outline seems remote, at best.

Styling

But it gets worse. Lets say we want to run with a pure HTML5 outline, and we use h1s everywhere. Remember, in the HTML5 spec the h1 is just a generic h element; its real level is determined by how deeply its nested in sectioning elements.

So how do we style it? Well, we could add class names to all our h1 elements so we can pick them out, but that is contrary to the stated HTML5 goal of simplifying authoring; and we may as well stick to h1-h6 (all of which are treated as generic h elements in a HTML5 outline).

We could try and style them through the cascade, but this quickly becomes absurd, as Nicole Sullivan has pointed out. In fact, ‘absurd’ only begins to describe it. When you consider the possible combinations of section, article, nav, and aside, and you want to create a generic style for a heading that’s, say, five levels deep (i.e. the equivalent of h5), you would have to write styles for all possible combinations, which gets absolutely ridiculous. Here’s the generic style for an h3 element:

article aside nav h1, article aside section h1, 
 article nav aside h1, article nav section h1, 
 article section aside h1, article section nav h1, article section section h1, 
 aside article nav h1, aside article section h1, 
 aside nav article h1, aside nav section h1, 
 aside section article h1, aside section nav h1, aside section section h1, 
 nav article aside h1, nav article section h1, 
 nav aside article h1, nav aside section h1, 
 nav section article h1, nav section aside h1, nav section section h1, 
 section article aside h1, section article nav h1, section article section h1, 
 section aside article h1, section aside nav h1, section aside section h1, 
 section nav article h1, section nav aside h1, section nav section h1, 
 section section article h1, section section aside h1, section section nav h1, section section section h1 { 
    font-size: 1.00em; 
 }

Yet that’s what HTML’s structural elements give us. What a mess.

Hungry for more? Part three of this article is now available and Luke’s book “The Truth About HTML5″ is available for a limited time through our sister site MightyDeals.com at an amazing 50% off.

Do you use article elements multiple times in a document? Are sections useful or should we stick with divs? Let us know your thoughts in the comments.

Featured image/thumbnail, uses structure image via Shutterstock.

0 shares
  • http://twitter.com/steve_fenton Steve Fenton

    The parts of this rant about backwards compatibility seem to forget how many billion web pages already exist and that won’t be updated ever. It is fundamentally important that the editor of the HTML specification protects these existing resources.

    Aside from that, I found the explanation of sectioning rather good here – that could definitely be turned into an article to help HTML5 authors understand and apply sectioning correctly.

    Headers and footers can be used in more places than authors expect, but this is optional. Having a specification that allows this is useful when you syndicate content that may already have headers and footers.

    • http://twitter.com/lukestevens lukestevens

      Regarding the billions of existing web pages, I agree! Ignoring that principle was the whole reason why XHTML 2.0 went nowhere. The problem was the HTML5 spec tried to have it both ways – introduce something new *while claiming it’s the same as it ever was*. This has lead to a big mess :)

  • Laurent Goderre

    The styling would not be an issue with a generic h by the simple addition to css. Since the browser generates the outline it can expose the level of a heading. This css syntax would be very clean. h[level=x]

  • Chris de Jong

    good article, right to the point!

  • 1076

    I’m eagerly anticipating the third installment, because so far it seems like you’re just not quite grokking what HTML5 is laying down.
    I’m hoping that you make a more clear point with the final part.

    To be more clear, everything so far seems to be saying “This is why HTML5 doesn’t do what I think HTML should do.”
    Which, to me, means nothing. I mean, if you don’t like to use it like that, that’s fine, it just doesn’t change how semantically appropriate the elements are. I haven’t seen a point yet that has been something more than a misrepresentation of the HTML5 spec, or a personal misconception about how the elements should be used. (Articles within articles, for example)

    I’m hoping that there are some more useful conclusions drawn from these personal concerns with the language.

    • http://twitter.com/lukestevens lukestevens

      Thanks for the comment. Part 3 is out now. Could you give an example of where I’ve misrepresented the HTML5 spec? I did hundreds of hours of research when writing my book, The Truth About HTML5, to avoid that kind of thing :)

  • http://twitter.com/zporterdesign Zachary Porter

    Just throwing this out there.. Why would you ever want to style headers five levels deep using the HTML tags like that? That’s what classes are for. The h1-h6 tags are used to simplify authoring by giving us a way to assign hierarchy and meaning in a way the browser and humans can both understand, not as CSS selectors. Sounds like a failure in using CSS more than a failure in the HTML5 spec..

    • http://www.facebook.com/shaw.brad Brad Shaw

      C’mon, it’s a hypothetical situation to illustrate a point. You seem to have missed the point.

  • Daniel M.

    Great article, in regards of SEO, how does Google and other search engines view a page with multiple h1 tags?

    • http://twitter.com/cmoralesweb Carlos Morales

      I’ve tried to get that question answered several times and no one seems to really know it.