Landmarks and where to put them
by Kilian Valkhof published on
Heading elements (h1
through to h6
) are used to give structure to the content of your page. They're important for SEO, make your pages more readable and, of course, also help people that use assistive technologies navigate through your page. Somewhat less known are landmark elements. These are elements that are used to define the structure of your entire HTML and you probably know some of them already: nav
, main
and footer
are all landmark elements (well, most of the time. We'll get to that.)
Many of these elements were only introduced with HTML5 (compared to the headers that have been with us for as long as HTML existed) so if you haven't used them extensively yet, that's not that unusual. Let's figure out what they are and where you can (and can not) use them.
Landmarks 101
When you look up landmark elements, you'll find that they also go by another name: sectioning elements. You can take that quite literally: they section off different parts of your page into unique semantic blocks.
Knowing which part of a website has which role is helpful to many. They can help browsers determine what part of the page to show in a reader mode, they let search engine know what pages on your site are most important (linked from the nav
) and they let users natively move focus to the main
content without you having to bring your own skip-links: assistive technologies can show a list of all landmarks and your visitors can use that to navigate across your page.
In other words, landmarks are a bunch of elements that help you define the structure of a page: you use them to show which set-of-links is the navigation (nav
), what part of the page is the intro (header
) and the main content (main
). If you page contains a stand-alone piece of content you could put that in an article
and if it contains secondary information you put that in an aside
. And if something it its own sectioned-off part you use ...a section
.
Here's an overview of the landmark elements in HTML, their ARIA role and what they mean:
aside
(role:complementary
) can be used to show content that is complementary to the main subject of the page. For example, links to related documents or meta info related to the main subject.footer
(role:contentinfo
) is where you put all the information about a page. Typically that's things like copyright info, related links, the authorform
(role:form
) can be a landmark element if it has a accessible name (set witharia-label
,aria-labelledby
ortitle
attributes)header
(role:banner
) is where your page's "introduction" goes. Things like your logo, search and main navigation all go in here.main
(role:main
) contains the main content or functionality of your page.nav
(role:navigation
) is where you provide navigational links. They can be for your entire website (think your main menu), but also for your current page (think table of contents).section
(role:region
) This is a "generic standalone section of a page". Essentially, if you have a part of the page that stands alone, try to go down this list and if none of them fit but it's still a separate part of the page, use a section. Likeform
s, it'll only be a landmark if it also has an accessible name.
There is still one more landmark that we need to discuss: the search
landmark. All the landmarks above are HTML elements with a specific landmark role, but the search
landmark role has no associated HTML element. It only exists in ARIA. As you might guess, the search landmark is used to indicate search functionality and practically, you'd add a search
role to a form
element to change it from a generic form to a search form.
Where (not) to put them: the ideal web page structure
Now that you know which landmarks there are, how do you use them in a web page? "The ideal web page structure" is quite a heavy promise, but we're limiting it to the ideal landmark structure. Here's what that looks like:
<header>
<!-- logo etc -->
<nav></nav>
<form role="search"></form> <!-- if it exists -->
</header>
<main>
<!-- what your page is all about -->
</main>
<aside>
<!-- complementary information -->
</aside>
<footer>
<!-- copyright notice etc -->
<nav></nav> <!-- if you want to -->
</footer>
Your page begins with the header
and ends with the footer
. Your navigation and search landmarks will usually go into the header
element and can sometimes fit well in the footer
element as well.
Directly after the header is the main
content. This is the most important part of your page so you put it as high as possible. Directly after the main
element you can put any complementary information that relates to your entire page.
What this does it create a "landmark outline" of your page that looks like this:
- Banner
- Navigation
- Search
- Main
- Complementary
- Contentinfo
- Navigation
Notice that unlike a heading structure, your landmarks don't add any hierarchy to a page. Each section of your page is meant to be its own part. It also doesn't matter how many other elements you add around or inside them. You are free to wrap everything in as many divs as your javascript framework requires you need to style your page.
When you add landmark elements, you're changing the semantics of your web page so there are some key things to keep in mind:
Not all nesting is created equally
Even though your landmarks don't add hierarchy, where you put your landmark elements will determine if they even are landmarks. Both header
and footer
elements are only landmarks if they are inside your body
element, but not if they're inside other sectioning elements.
A header
/footer
in any of the following elements indicate they're the header or footer for just that sectioning element, and they are taken out of the landmark structure:
article
aside
main
nav
section
Depending on who you ask (the ARIA authoring practice guide, in this case), adding an aside
into any of the above is also a bad idea. If something is complementary then by definition it's not part of the main
or article
. This doesn't track with the official HTML5 specification, that has examples of using aside
for things like pull quotes in articles.
Neither is correct or wrong, but keep in mind though that the more landmarks you add, the longer it takes assistive tech to go through the list of landmarks and the more annoying it will be for your visitors.
Sometimes just adding landmark elements isn't enough
As mentioned in the overview of landmarks, just adding a form
or section
won't make them landmarks. You need to give them an accessible name or explicit role, and there's a few ways to do that:
- Adding a
aria-labelledby
attribute that contains theid
of another element with the title of the form or section. - Adding a
aria-label
ortitle
attribute to the element. The title attribute will also be visible on hover so keep that in mind. - Adding an explicit
role
attribute withform
orregion
as the value.
You can't just keep adding them
The banner
, contentinfo
and main
landmark roles should only be added to your page once. There is nothing in HTML5 that prevents your site from having multiple of them but from a semantic standpoint it doesn't make sense and for people using assistive technologies it's confusing. Your page should have one header, one footer and one main area. If you need more, maybe you just need another page.
Naming landmark elements
If you have multiple of the same elements, for example you use a nav
element for your top-level website navigation, and also for the table of contents on a page, you should give each of them a unique accessible name. If you don't, then visitors using assistive technologies will not know which is which. You can add a name using aria-labelledby
, aria-label
or title
attributes.
When adding a name to a landmark element, it can be very tempting to add the role as well because that's how you would describe it in natural speech. For example, for your top level navigation you might want to add an aria-label
of "Main navigation".
If you do that however, what assistive technology will announce is "Main navigation navigation" and your visitor gets to hear that it's navigation twice. Assistive technogies already append the role, so you shouldn't. In this case, naming your navigation "Main" is enough.
Don't just replace your div
s with section
s
A div is not a button, and a section is not a div. When HTML5 just came out, a lot of advice boiled down to "Use section elements because they're more semantic than divs" but of course, that only works if the divs you replace had semantic value. For the most parts, your div
s wont have any specific semantics: they don't tell the browser what each part of the structure is for.
And that's fine! You can use your divs for styling, to structure your DOM in such a way that you can use CSS and JavaScript to build what you want to build. And when you have a portion of the page that is it's own standalone or self-contained part, you can add a section (and make sure to name it).
On Roles and Elements
Throughout this article I've used Elements (e.g. header
) and Roles (e.g. banner
). So what's with those? Are they the same thing? Why do they have different names?
HTML5 is the official specification in terms of what elements have what semantic value. However, the HTML5 specification doesn't cover all possible semantics. To provide richer semantics, ARIA was created as a technology that sits on top of HTML that can help "plug the gaps".
It's generally better to use HTML where possible: the first rule of aria is don't use aria:
If you can use a native HTML element or attribute with the semantics and behavior you require already built in, instead of re-purposing an element and adding an ARIA role, state or property to make it accessible, then do so.
Practically this means that instead of adding a role="banner"
to your div to make it a header element, you should just use the header
element.
So why does role="banner"
exist? It exists for some very pragmatic reasons: While yes, using a header element is better, not all websites are started anew, and not all websites are built with modern systems. Some systems might have no way of adding a header
element. In those systems, using a role
attribute means that you can still provide the correct semantics.
If you write HTML you should always prefer to use the HTML elements and if you do, you don't have to add the role
attribute (there are some places where you should, but they're not landmark-related).
As for the names being different: for better or for worse ARIA and HTML are written by different people in different places, with different needs. While for ARIA it makes sense to call the navigation "navigation", HTML authors would go crazy if for every menu they had to write <navigation>
instead of just <nav>
. The names in ARIA in comparison are written to also make sense outside of the concept of a HTML page. A page has a footer, but any bit of content might have "content info" that gives additional information.
Wrapping up
Your page should almost certainly have a top level header
, main
and footer
, but you don't want to add a bunch of them. If it's part of a larger website then you'll want to use a nav
element to link to other pages. If you use multiple nav
elements you'll want to name them so your visitor can tell them apart. You should try and use the HTML elements but if you absolutely can not, ARIA gives you the role
attribute. Landmarks have a name and a role, and both get read out by assistive technologies.
Used resources:
https://www.w3.org/WAI/ARIA/apg/example-index/landmarks/HTML5.html
https://developer.mozilla.org/en-US/docs/Web/HTML/Element#content_sectioning
https://www.w3.org/TR/wai-aria-1.2/#landmark
About Kilian Valkhof
Kilian Valkhof is a web developer from The Netherlands. He writes about HTML, CSS, JS and A11Y on his blog at kilianvalkhof.com and he's currently working on Polypane, the web browser that helps you build more responsive, more accessible and faster websites. It has hundreds of neat features, but one of the things it does is show an overview of all page landmarks with tips and checks while you work. If that sounds useful, check it out!