Understanding ARIA Landmarks - General Principles and Roles
Tags: a11y, html, webdev
Published: 2021-02-15 11:48:16

ARIA landmarks are a set of ARIA roles that are provided to our HTML elements in order for us to identify the structure of a web page. When we visit a webpage, we get a sense of its visual structure from the beginning but this structure should also be present in our markup.

We should use ARIA landmarks for a number of reasons:

1. We are getting semantic markup that represents our visual structure. Perceivable content should have a semantically meaningful landmark.

2. Keyboard navigation is supported for screen reader users. Screen reader users can navigate the web page based on its page structure.

3. We can create skip links that can enhance keyboard navigation for both screen reader users and sighted users. 

## ARIA General Principles

The [World Wide Web Consortium (W3C)](https://www.w3.org) has provided us with some [ARIA landmarks general principles](https://www.w3.org/TR/wai-aria-practices/examples/landmarks/index.html).

### 1: Identify the logical structure of a web page

What this means is that we should really think about the structure of our web page. We should break our page into perceivable areas. We can also break our page into further sub-areas if needed. 

### 2: Assign landmark roles to each area

We should assign landmark roles to each area of our web page. Roles such as **banner**, **main**, **complementary** and **contentinfo** should be top/root level landmarks.

### 3: Label each area

This principle is very important especially for users who are using assistive technologies. 

- If a webpage has multiple landmarks in its markup, then the label for each landmark should be unique.

An example of this is when we have multiple `navigation` landmarks. We could have primary and secondary navigations on our webpage. So we should give each a unique label. The first navigation should have an [aria-label attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute) with a value of `primary`. The secondary navigation should have an aria label of `secondary` or whatever makes sense in that context. 

- If a landmark area begins with a [heading level element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements) then we can provide an [aria-labelledby attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-labelledby_attribute) to that area.


- Screen readers announce the type of landmark we are currently visiting. Therefore we can omit the landmark from any labels provided to the element. 

An example of this can be seen above when we use `Primary` instead of `Primary Navigation` in the label. If we kept `Primary Navigation` then the screen reader would announce `Primary Navigation Navigation` which may be confusing for the user. 

Here is some examples of these types of labels:

```
<nav role="navigation" aria-label="primary">
   // code here
</nav>
<nav role="navigation" aria-label="secondary">
   // code here
</nav>
<aside role="complementary" aria-labelledby="notice">
 <h2 id="notice">Site Notice</h2>
</side>
```

## A list of ARIA landmarks

### Top-level landmarks 

Top-level landmarks stand for landmarks that are not contained within any other landmarks. For each of these landmarks, the ARIA landmark design principles are worth reading.

- [banner](https://www.w3.org/TR/wai-aria-practices/examples/landmarks/banner.html)  - this represents **site-oriented** content such as a logo or site search. This role should appear at the start of each web page.

- [contentinfo](https://www.w3.org/TR/wai-aria-practices/examples/landmarks/contentinfo.html) - this is to represent the **footer** of a webpage.

- [main](https://www.w3.org/TR/wai-aria-practices/examples/landmarks/main.html) - this is to represent the **primary content** of a webpage.

- [complementary](https://www.w3.org/TR/wai-aria-practices/examples/landmarks/complementary.html) - represents the **supporting content** of a web page.

### Other landmarks 

- navigation

- region

- form

- application

- search

You can read about all of these [ARIA landmarks](https://www.w3.org/TR/wai-aria-practices/examples/landmarks/HTML5.html) on the W3 website.


## HTML sectioning elements

Before HTML5 was introduced, we would have had to apply these ARIA landmarks to elements like `divs` in order for us to convey the structure of the webpage in our markup. 

For example, a header section might look like the following:

```
<div role="banner" id="header">
  // site-oriented content goes here
</div>

```

HTML5 introduced some new [sectioning elements](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_HTML_sections_and_outlines) that provide ARIA landmarks by default.
 

| Element | Default Landmark Role          | case   |   |   |
|---------|---------------|---|---|---|
| main    | `main`        | always  |   |   |
| nav     | `navigation`   |  always  |   |   |
| aside   | `complementary` |  always  |   |   |
| header   | `banner` |  only when top level element  * |   |   |
| footer   | `contentinfo` |  only when top level element * |   |   |

* The `footer` element no longer has the `contentinfo` role and the `header` element no longer has the `banner` role when they are descendants of `section`, `main`, `nav`, `aside` or `article` elements.

The `section` element has the role of `region` and the `form` element has the role of `form` only when they have an accessible label by using the `aria-label`, `aria-labelledby` or `title` attribute. Some of these labeling methods were mentioned above.

Let's see this in action.

If we visit the homepage of the [CSS Tricks website](https://css-tricks.com/) and open up our browser developer tools and navigate to its elements panel. Press Cmd + Option + C (Mac) or Ctrl + Shift + C (Windows, Linux, Chrome OS) to open it up. 

This is what you should see:

![The CSS tricks home page opened up on chrome dev tools elements tab](https://cdn.hashnode.com/res/hashnode/image/upload/v1613385873373/YP-MckYSO.png)

Now, we can see a few elements in the elements panel. If we inspect the page we can see some sectioning elements such as `header`, `main`, `section`, and `footer`. If we inspect the header, we can't see anything about its role without viewing its accessibility information.

To do this, we need to visit the accessibility panel for that element. This will be on the bottom menu where we have our styles.

The menu will look something like this:

![The bottom menu panel in the chrome dev tools elements tab](https://cdn.hashnode.com/res/hashnode/image/upload/v1613386144119/fkvdvFj9L.png)

Click on the `Accessibility` tab. Do you notice anything about its role?

![The accessibility tab in chrome dev tools showing the header element with a default role of banner](https://cdn.hashnode.com/res/hashnode/image/upload/v1613386246498/MhfQEGRiO.png "Header element role of banner")

We can see that by default it is given the role of `banner`. This is because the `header` element has a role of banner provided already by this element when it's in the context of the body element. 

### Wrapping Up

At the time of writing, Internet Explorer (IE) 11, 10, and 9 support all sectioning elements except the `main` element which only has [partial support for sectioning elements](https://caniuse.com/html5semantic). Support on other browsers is relatively good but it's best to refer to the caniuse website for more information.

Landmarks are supported by most major screen readers and Scott O'Hara wrote a really great article about [Accessible Landmarks](https://www.scottohara.me/blog/2018/03/03/landmarks.html).

For all elements, if you need to support IE version 8 or below then you will need to style each element as a `block` level element and use some JavaScript to create the element if it is not supported.

Depending on your browser support requirements, it is suggested to manually test the browsers you support and use various screen readers in each test. 

If you enjoyed this blog and would like to see similar content in the future, or would like to get in touch then please follow me on [Dev.to](https://dev.to/garybyrne), [Twitter](https://twitter.com/garybyrne1995) and [Hashnode](https://hashnode.garybyrne.codes).