Using the main element
I’ve just changed my site to use the new <main> element. It took about 1 minute to work out what was wrong with my CSS, until I realised that I hadn’t defined main {display:block;}
(the CSS spec says that all elements are inline by default, unless over-ridden). I expect that the HTML5 shiv will add this in, but I don’t use the shiv (it was written after I converted the site). If you use the html5shiv on GitHub, the latest version includes support for <main>.
If you use something like <div id=”main”> (or similar, such as <div id=”content”> as I was), simply replace that with <main role=”main”>.
The <main> element is an exact analogue of ARIA’s role="main"
, and is designed to show screenreaders and assistive technologies exactly where main content begins, so it can be a target for a “skip links” keyboard command, for example. It could also be used for content syndication (Instapaper-ish things); mobile browsers could zoom in on <main> when encountering non-responsive websites.
It should therefore be used once per page. Therefore, the WHATWG spec is wrong when it says “The main element can be used as a container for the dominant contents of another element.” as this suggests that it may be used multiple times. Don’t. Otherwise, the benefits will be lost.
The W3C version of the spec is far more accurate and useful:
The main element represents the main content section of the body of a document or application. The main content section consists of content that is directly related to or expands upon the central topic of a document or central functionality of an application…
Authors must not include more than one main element in a document.
Authors must not include the main element as a child of an article, aside, footer, header or nav element.
The new element is already in Firefox and Chrome nightlies. The beauty of <main> is that it is already supported in modern assistive tech. Most of these understand aria role=main, as browsers map this to an operating system thingummy (technical term). The thingummy is what the assistive technologies interface with. So in FF nightly and webkit, the new <main> element is mapped to the same thingummy – therefore screenreaders and the like can use it straight away.
Nevertheless, I’m still using ARIA role="main"
on the new element as belt-and-braces because you’re almost certainly not using Firefox or Chrome nightlies, and there’s no support yet in Opera or Internet Explorer.
Although I was initially opposed to the new element, I’m firmly in favour of using it, once per page, to give extra built-in accessibility to those who need extra help accessing the Web.
And hearty congratulations to Steve Faulkner, The Paciello Group‘s Kylie Minogue of web accessiblity, for his research and perseverance in getting this in the spec and in some browsers.
Buy "Calling For The Moon", my debut album of songs I wrote while living in Thailand, India, Turkey. (Only £2, on Bandcamp.)
34 Responses to “ Using the main element ”
Hi Bruce,
I’m still a bit non-plussed by the whole main thing. I guess the example you provide for <main role=”main”> is reasonable. But, as you may have already seen, there are plenty of people not happy with just one main per page: http://adactio.com/journal/6014/ (via ALA which is quite sad really). Reactions like that highlight the problem of trying to overload HTML 5 syntax with use cases and hoping developers will play nicely.
@charlie
there are plenty of people not happy with just one main per page
An overstatement. What it is true to say is that there are plenty of people who have been involved in the development of main and how it is defined who have not called for it to be changed in the way Jeremy describes.
Reactions like that highlight the problem of trying to overload HTML 5 syntax with use cases and hoping developers will play nicely.
Finding it difficult to make sense of this bit. main and its current conformance requirements are based on a common markup pattern used in approximately 40% of web pages. i.e. the use of a div to identify the main content with an id=main or similar, sometimes with a role=main added or used as the target for a skip link. What main does is take this informal markup pattern and give it some balls to the benefit of users.
MAIN as defined by the W3C solves the problem of needing a consistent top level element for content; for all the good reasons Steve has explained through this process.
MAIN as defined by WHATWG solves the problem of needing a common element to go between HEADER and FOOTER wherever they legally appear. But in doing so, it ignores the actual reasons for adding MAIN and sabotages the a11y benefits.
Both problems should be solved. HTML5 should always have had, say, a CONTENT element to go between HEADER and FOOTER; and it should have always had a solution for identifying the content defined by ARIA’s banner, main and contentinfo.
In a perfect world, HTML5 would always have had a complete set of elements, something like:
HEADER, CONTENT, FOOTER
MAINHEADER, MAINCONTENT, MAINFOOTER
OR just H/C/F and an algorithm where the first set of sibling H/C/F within the BODY were presumed the MAIN versions (allowing for the fact they might be wrapped in layout DIVs). Scooby Doo-ish, but based on author declarations instead of author omissions.
A compromise solution now would be to add another element which does the WHATWG’s version. Say, CONTENT. So, MAIN can do what W3C has specced; CONTENT can do what WHATWG specced. Both problems would be solved. The we just need to figure out what to do about banner and contentinfo…
HEADER, CONTENT, FOOTER, MAINHEADER, MAINCONTENT, MAINFOOTER
Oh no, this is exactly what we don’t need! A sort of Borgesian taxonomy (“Celestial Emporium of Benevolent Knowledge” in THE ANALYTICAL LANGUAGE OF JOHN WILKINS)* of possible use cases which will defeat the purpose of HTML5, the choice of tags for which was based on empirical research or what people were using.
I understand the argument for <main>, though I am remain more convinced by Bruce’s original argument against it: for a programmer and a designer working with a page, the “main” area of content is what is left once everything else has been parcelled into navigations, headers, footers and asides. Having recently done a spate of breakdowns of page designs into HTML5 blocks I remain convinced of this especially for pages that essentially only catalogue other content – typical for many homepages. <main> just adds noise.
I spend little time dealing with ARIA stuff but I do see problems trying to force HTML tags to do more than provide semantic structure. I’m starting to see tags like <nav role=”navigation”> which is to me simply unnecessarily and distractingly redundant. 1:1 tag to role mappings can be handled more explicitly so that <nav> always has the role “navigation”. <main> would, therefore, always be role main and there should be the necessary safeguards to ensure there is only one per page so that accessibility is not compromised.
what is “the problem of needing a common element to go between HEADER and FOOTER wherever they legally appear” ?
The header/body/footer pattern is everywhere in web pages and it’s repeated down through the DOM on large sites (even most blogs, although blogs usually aren’t big enough for serious repetition).
HTML5 gives us ways to declare sections of content; then gives us ways to declare the header and footer inside those sections of content. But for the actual content all we get is a DIV, semantically relying on the omission of intent to decide the author’s intent was “that div there is the content”.
It’s semantically vague; and technically inconsistent and confusing, two things you want to avoid in any sizeable code standard (say a large-scale CMS or application worked on by large numbers of devs). It also adds complexity because you cannot rely on elements alone, you must add in an identifier on the content DIV because it’s not the only thing in there.
So in your CSS, you end up with things like this:
.foo header,
.foo .content,
.foo footer {}
On a small site this probably doesn’t matter. Building in the large, inconsistency like this is a pain: your code standard is harder to remember and your selector weights are inconsistent (tends to give you a higher bug rate).
So you end up normalising it:
.foo .header,
.foo .content,
.foo .footer {}
…because then your content doesn’t need a different selector weight any time it needs to be adjusted somewhere across the code base. Admittedly it’s slightly stronger than it could have been with elements but that’s one of the myriad tradeoffs you make (noting that at the top level without MAIN this problem repeats, only with sledgehammer level ID selectors). Also with the normalised classes your code standard is easier to remember for the devs using it.
Then there’s the further problem added on commercial sites, which regularly includes adverts inside the pattern:
header
div.content
div.ad
footer
Scooby Doo just told you an ad was content. But what if we had an element for the author to actually declare the content?
header
content
div.ad
footer
The author has removed the ambiguity. All the things with a serious role have been marked up. Scooby’s still finding the villain, but he’s not accidentally accusing your content 😉
@Ben I notice that <article> is conspicuous by its absence in your example.
@charlie: ARTICLE would be a logical choice for the .foo wrapper in my example, but it is not particularly relevant to the absence of a content element to put inside it.
Reading back I suppose my example is ambiguous. When I talk about an element to go between header and footer I’m not talking about the banner and contentinfo instances of header and footer – we have MAIN for that now. I’m talking about the header and footer instances further down the DOM where MAIN doesn’t help.
The missing element would drop into the W3C’s example for ARTICLE like this…
<article>
<header>
<h1>The Very First Rule of Life</h1>
<p><time datetime="2009-10-09">3 days ago</time></p>
</header>
<strong><content></strong>
<p>If there's a microphone anywhere near you, assume it's hot and
sending whatever you're saying to the world. Seriously.</p>
<p>...</p>
<strong></content></strong>
<footer>
<a href="?comments=1">Show comments...</a>
</footer>
</article>
So the WHATWG spec for MAIN does what I want lower down the DOM; but it’s still not an overall solution because it breaks the accessibility gain the W3C spec gives at the top level.
Odd, that code example previewed ok. Ahh well! 🙂
@charlie
though I am remain more convinced by Bruce’s original argument against it: for a programmer and a designer working with a page, the “main” area of content is what is left once everything else has been parcelled into navigations, headers, footers and asides. Having recently done a spate of breakdowns of page designs into HTML5 blocks I remain convinced of this especially for pages that essentially only catalogue other content – typical for many homepages. just adds noise.
Meanwhile in the real world when the code of 8000 or so home pages is reviewed we find that marking up all content into appropriate parcels is not what happens. And how does replacing a div element with main element add noise?
I do see problems trying to force HTML tags to do more than provide semantic structure. I’m starting to see tags like which is to me simply unnecessarily and distractingly redundant. 1:1 tag to role mappings can be handled more explicitly so that always has the role “navigation”. would, therefore, always be role main and there should be the necessary safeguards to ensure there is only one per page so that accessibility is not compromised.
The majority of HTML elements are mapped by browsers to accessibility APIs. This has been the case for many years. Use of roles in the cases you cite are simply polyfilling to make up for the lack of support in some browsers. For example is mapped to navigation in Firefox and Safari but not in IE. main is a new element which landed in browsers last week, in the browsers it is implemented in, the mapping is already supported, again the addition of role=main is a polyfill.
@Steve
thanks for the information on the roles/tags stuff. I remain unconvinced that we will see significant takuep of <main> in websites. Given the still parlous state of implementations of other parts of the HTML 5 spec (forms, time) it’s a bit weird to see this getting support in Chrome and Firefox nightlies so quickly. Then again, it doesn’t actually do very much.
Regarding markup, however, there is no need to be so patronising. 8000 websites sounds a lot but is statistically irrelevant. Opera’s MAMA was closer to the mark back in 2008 and was AFAIK important background for HTML 5.
@charlie,
Regarding markup, however, there is no need to be so patronising. 8000 websites sounds a lot but is statistically irrelevant. Opera’s MAMA was closer to the mark back in 2008 and was AFAIK important background for HTML 5.
My apologies, the data cited as evidence for the addition of the new html5 structural elements was a study carried out by Google in 2005. Unfortunatley not even a subset of the raw data was provided, and only a quite limited high level analysis of the data was ever made public. So we have to take it on faith. I have asked on many occasions for The mama data was not used as far as I am aware. The mama data was used and cited in the researching/developing of the main element though.
@charlies
I misquoted it’s actually around 35,000 home pages (out of the worlds top 50,000 most visted web sites) provided in the data set cited, which I would suggest is quite statistically significant, and can provide a good indication of markup trends and practices that are evident in sites used daily by many millions of people. As the data was collected a month or so ago it provides an up to date an relevant point of reference for understanding how HTML is being used.
A commenter named Charlie wrote:
“But, as you may have already seen, there are plenty of people not happy with just one main per page: http://adactio.com/journal/6014/ “
Well, it’s not that I’m not happy — I just wanted to have a discussion about the possibility of expanding the use of the main element while still keeping the body’s main element (and only that instance of the main element) mapped to the aria role of “main”.
But I’m very happy to have an element that corresponds to the last ARIA landmark role that (until now) didn’t have a 1-to-1 mapping with a native HTML semantic. I’d just like to see it work more like other ARIA landmark roles that should only be used once per document (banner, contentinfo) where the corresponding HTML elements can be used within sectioning content (header, footer).
Charlie went on to say:
” (via ALA which is quite sad really)”
So sad. So very, very sad.
…the purpose of HTML5, the choice of tags for which was based on empirical research or what people were using.
FWIW, that was not the case. The WHATWG’s refusal to follow other obvious patterns (article/comment) shows that research isn’t really here or there.
I haven’t followed the development of main very closely – what persuaded the WHATWG to add it to their spec?
@Luke
what persuaded the WHATWG to add it to their spec?
Hixie added it to his spec because is has been implemented in browsers.
Well, you all are FAR more intelligent than I (I’m but a humble web developer and teacher of web design), but I’m strongly in favor of Jeremy’s recommendation. It’s consistent, accessible, easy to implement, easy to teach, easy to style, tastes great and is less filling.
@ben
its not about being intelligent, Bruce for example struggles with many of the more complex topics of web development and life in general (dressing for example). It is about having an understanding of the standards development process, and that features don’t get implemented or modified on a whim. Plus ones don’t count for much, but use cases and data to back up a feature request do.
[…] Using the main element […]
[…] Using the main element (Bruce Lawson) […]
[…] Using the main element […]
[…] – Using the main element “The beauty of <main> is that it is already supported in modern assistive tech. Most of […]
[…] Using the <main> element […]
[…] of concerns that override what I’ve noted above. And at the end of the day, it’s what won out. Bruce Lawson has a good write-up. After a few quick tweaks to reset stylesheets, shivs, and the like, I’ve already started using […]
[…] Using the main element http://www.brucelawson.co.uk/2013/the-main-element/ […]
[…] Using the main element http://www.brucelawson.co.uk/2013/the-main-element/ […]
[…] Using the main element http://www.brucelawson.co.uk/2013/the-main-element/ […]
[…] Bruce Lawson — Using the main element […]
[…] Bruce Lawson — Using the main element […]
[…] Using the main element […]
[…] Bruce Lawson — Using the main element […]
Note that in the HTML 5.1 spec (not WHATWG) it says:
This aspect of main, while not yet implemented is being actively pursued with browser vendors, and will further increase the utility of this feature to any keyboard user.