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.

VoiceOver on macOS showing the lis of landmarks for htmhell.dev.

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 author
  • form (role: form) can be a landmark element if it has a accessible name (set with aria-label, aria-labelledby or title 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. Like forms, 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:

  1. Adding a aria-labelledby attribute that contains the id of another element with the title of the form or section.
  2. Adding a aria-label or title attribute to the element. The title attribute will also be visible on hover so keep that in mind.
  3. Adding an explicit role attribute with form or region 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 divs with sections

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 divs 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

https://html.spec.whatwg.org

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!