Landmark roles

David made a comment on Twitter about some markup he was working on:

Feels dirty setting id’s on main HTML5 page header and footer, but overriding inheritance they cause seems needlessly laborious.

I know the feeling. I don’t like using IDs at all, unless I want part of a document to be addressable through the fragment identifier portion of the URL. While I think it’s desirable to use the id attribute to create in-document permalinks, I don’t think it’s desirable to use the id attribute just as a styling hook. Its high specificity may seem a blessing but, in my experience, it quickly leads to duplicated CSS. IDs are often used as a substitute for understanding the cascade.

Nicole feels the same way about ID selectors, and she knows a thing or two about writing efficient CSS.

Back to David’s dilemma. Let’s say you’re targetting header and footer elements used throughout your document in sections, articles, etc. All you need to use is an element selector:

header {
// regular header styles
}

But what about the document-level header and footer? They’re probably styled very differently from the headings of sections and articles.

You could try using a child selector:

body > header

But there’s no guarantee that the document header will be a direct child of the body element. Hence the use of the id attribute—header id="ID":

header#ID {
// page header styles
}

There is another way. In HTML5 you can, for the first time, use ARIA roles and still have a valid document. ARIA landmark roles add an extra layer of semantics onto your document, distinguishing them as navigational landmarks for assistive technology.

Some of these landmark roles—like IDs—are to be used just once per document:

Within any document or application, the author SHOULD mark no more than one element with

That’s useful for two reasons. One, the existence of role="main" means it is not necessary for HTML5 to provide an element whose only semantic is to say “this is the main content of the document.”

A lot of people have asked for such an element in HTML5. “We’ve got header, footer and aside,” they say. “Why not maincontent too?”

But whereas header, footer and aside can and should be used multiple times per document, a maincontent element would, by necessity, only be used once per document. There are very few elements in HTML that are like that: the html element itself, the title element, head and body (contrary to popular opinion—likely spread by SEO witch-doctors—the h1 element can be used more than once per document).

Now the desired functionality of semantically expressing “this is the main content of the document” can be achieved, not with an element, but with an attribute value: role="main".

The rough skeleton of your document might look like this:

<header role="banner"></header>
<div role="main"></div>
<footer role="contentinfo"></footer>

Now you can see the second advantage of these one-off role values. You can use an attribute selector in your CSS to target those specific elements:

header[role="banner"] {
// page header styles
}

Voila! You can over-ride the default styling of headers and footers without resorting to the heavy-handed specificity of the ID selector.

And, of course, you get the accessibility benefits too. ARIA roles are supported in JAWS, NVDA and Voiceover

Have you published a response to this? :