Chapter 1. Structuring Documents

This book focuses on writing accessible components, but accessibility begins at the very first line of your HTML document. Your components live on a page, and your page is part of a document. Several elements, especially in the <head> of your document, affect accessibility.

1.1 Define the Natural Language

Problem

If a page doesn’t contain an explicit definition of the natural language it’s written in, software may not be able to translate content correctly. The term natural language refers to the language you use for the content on the page, not the programming language. This lack of information can result in faulty translations, wrong formatting, and content being hard to understand for screen reader users.

Solution

You can define the natural language of a page by using the lang attribute on the <html> element. See Example 1-1.

Example 1-1. English defined as the natural language of the page
<!DOCTYPE html>
<html lang="en">
</html>

You can also define a specific dialect of the base language. See Example 1-2.

Example 1-2. British English defined as the natural language of the page
<!DOCTYPE html>
<html lang="en-GB">
</html>

The lang attribute is global, meaning you can use it on any element, although it may not affect some of them. It can be helpful if a page is written in one language but contains text passages or even single words in other languages. See Example 1-3.

Example 1-3. Transliterated Japanese in Latin script used on a page written in English
<!DOCTYPE html>
<html lang="en">
  <head></head>
  <body>
    <p>
      The Wind-Up Bird Chronicle (<span lang="ja-Latn">Nejimakidori Kuronikuru
      </span>) is a novel published in 1994 by Japanese author Haruki Murakami.
    </p>
  </body>
</html>

Use the lang pseudoclass to adjust the typography and layout for specific languages. See Example 1-4.

Example 1-4. Selecting all elements in the Serbian language
:lang(sr) {
  font-family: 'Cyrillic font', sans-serif;
}

Discussion

Assistive technology and other software may not be able to determine the natural language of a page automatically. Certain features in HTML and Cascading Style Sheets (CSS) rely on that information to help localize software content and provide an excellent overall user experience. You must set the language of each page programmatically and explicitly by using the lang attribute on the <html> element, as shown in Example 1-1. For passages of text written in a different language than the primary language of the page, you can also use the attribute, as shown in Example 1-3. That allows screen readers to improve pronunciation by switching voice profiles accordingly for certain words or sentences. Try to do this sparingly because switching voice profiles can be annoying because it interrupts the reading flow. For well-established foreign words, it might not be necessary. Examples in German are English words like “Download,” “Workshop,” or “Link.”

Usage

The value of the lang attribute must be a valid BCP 47 language tag, composed from one or more subtags. A subtag is a sequence of alphanumeric characters distinguished and separated from other subtags by a hyphen.

The language subtag is a 2- or 3-character code that defines the primary language: for example, en for English, de for German, or fr for French, as shown in Example 1-5.

Example 1-5. Spanish defined as the natural language of the page
<html lang="es"></html>

The optional script subtag is a 4-character code that defines the writing system used for the language, as shown in Example 1-6.

Example 1-6. A name in Cyrillic script next to the same name in Latin script marked as such
Никола Јокић (<span lang="sr-Latn">Nikola Jokić</span>).

The optional region subtag is usually a 2-character country code written in all caps and defines a dialect of the base language, as shown in Example 1-7.

Example 1-7. Austrian German defined as the natural language of the page
<!DOCTYPE html>
<html lang="de-AT">
</html>

You should use the 2-character primary language code and add region subtags only when it is necessary to differentiate content in different dialects that may not be mutually understandable. At least for screen reader users, not adding region subtags shouldn’t make a difference because they’re typically ignored by the software.

You can find a list of all tags and subtags in the BCP 47 language subtag lookup.

Benefits

The lang attribute is powerful and affects many aspects of web accessibility and user experience in general. These include:

Assistive technology

Speech synthesizers that support multiple languages adapt their pronunciation and syntax to the language of the page, speaking the text in the appropriate accent with proper pronunciation. For a page with German content where the language of the page is set to English (lang="en"), the screen reader software may pick an English synthetic voice profile and read the German text with English pronunciation. If you set no language, screen readers may fall back to the users’ default system setting, which might not be appropriate. The result can be hard to understand, confusing, or even completely wrong. All screen readers support numerous languages. Some software switches language automatically, while for others users have to install and configure language voices or packs manually.

The attribute definition also allows Braille translation software to optimize the output and prevent it from erroneously creating Grade 2 Braille contractions.

Translation

Translation tools like Google Translate use the information from the lang attribute to translate content on the page. While this kind of software is usually good at automatically detecting the language of the page, a mismatch between the actual language and the defined language can yield unexpected and unwanted translations.

Quotes

Quotation marks may change depending on the natural language of the page. For example, English uses different quotation marks than German or French, and the correct lang helps browsers pick the proper glyphs, as illustrated in Examples 1-8, 1-9, and 1-10.

Example 1-8. Automatic quotation marks using the <q> element in English
<p lang="en">
  <q>A quote in English.</q>
</p>

<!-- Results in: “A quote in English.” -->
Example 1-9. Automatic quotation marks using the <q> element in German
<p lang="de">
  <q>Ein Zitat auf Deutsch.</q>
</p>

<!-- Results in: „Ein Zitat auf Deutsch.“ -->
Example 1-10. Automatic quotation marks using the <q> element in French
<p lang="fr">
  <q>Une citation en français.</q>
</p>

<!-- Results in: « Une citation en français. » -->

Hyphenation

lang may affect hyphenation in CSS. See Example 1-11.

Example 1-11. A paragraph with a maximum width of 28 characters and hyphenation turned on
p {
  max-width: 28ch;
  hyphens: auto;
}

In Examples 1-12, 1-13, and 1-14, you can see how the same paragraph written in German, given a different lang attribute value, renders differently in Google Chrome. Words either don’t break at all or break at different positions. Only the first and the second examples are correct. It’s worth noting that browsers behave differently.

Example 1-12. Correctly hyphenated German text in a paragraph defined as German
<p lang="de">
  Weit hinten, hinter den Wortbergen, fern der Länder Vokalien und Konsonantien
  leben die Blindtexte. Abgeschieden wohnen sie in Buchstabhausen an der Küste
  des Semantik, eines großen Sprachozeans. Ein kleines Bächlein namens Duden
  fließt durch ihren Ort und versorgt sie mit den nötigen Regelialien.
</p>

<!-- Results in:
  Weit hinten, hinter den Wortbergen,
  fern der Länder Vokalien und Konso-
  nantien leben die Blindtexte. Abge-
  schieden wohnen sie in Buchstab-
  hausen an der Küste des Semantik,
  eines großen Sprachozeans.
-->
Example 1-13. No hyphenation of German text in a paragraph defined as English
<p lang="en">
  Weit hinten,…
</p>

<!-- Results in:
  Weit hinten, hinter den Wortbergen,
  fern der Länder Vokalien und
  Konsonantien leben die Blindtexte.
  Abgeschieden wohnen sie in
  Buchstabhausen an der Küste des
  Semantik, eines großen
  Sprachozeans.
-->
Example 1-14. Wrong hyphenation of German text in a paragraph defined as French
<p lang="fr">
  Weit hinten,…
</p>

<!-- Results in:
  Weit hinten, hinter den Wortbergen,
  fern der Länder Vokalien und Konso-
  nantien leben die Blindtexte. Abges-
  chieden wohnen sie in Buchstabhau-
  sen an der Küste des Semantik, eines
  großen Sprachozeans.
-->

Font selection

Browsers may select language-appropriate fonts for displaying details in ideographic characters that vary from language to language, such as Chinese, Japanese, and Korean (known as the “CJK languages.”)

Search Engine Optimization (SEO)

Properly defining the natural language can improve the quality of search results by helping search engines with localization.

Form controls

In some browsers, the lang attribute also affects the formatting in form controls. For example, Firefox shows the correct decimal characters in number input fields depending on the language.

1.2 Describe the Document

Problem

Screen reader users navigating a website can’t always tell which page they’re on. They may not understand what a page is about or notice that content has changed if the page’s title isn’t set correctly.

Solution

You can name pages using the <title> element in HTML. The title must be unique and must describe the topic or purpose of each page concisely. See Example 1-15.

Example 1-15. A succinct and descriptive page title
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Products - Johanna’s Toy Store</title>
  </head>
</html>

For social media previews, you can optionally use an open graph meta tag to include more or different information, as shown in Example 1-16.

Example 1-16. A catchier page title for social media previews
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Products - Johanna’s Toy Store</title>
    <meta property="og:title"
          content="Find dolls, toy cars, and more in Johanna's Toy Store">
  </head>
</html>

Adding context depending on the state of the page can be helpful (see Examples 1-17, 1-18, 1-19, and 1-20).

Example 1-17. The title includes the current step and the total number of steps in a checkout process
<title>Checkout (step 3 of 4) - Johanna’s Toy Store</title>
Example 1-18. Number of validation errors in the title of a sign up page
<title>2 errors - Sign Up - Johanna’s Toy Store</title>
Example 1-19. Number of results in a search page’s title
<title>21 results for term “crocodile” - Johanna’s Toy Store</title>
Example 1-20. The title indicating the current search results page
<title>Page 2 - Product Search Results - Johanna’s Toy Store</title>

Discussion

Sometimes it takes work to get oriented on a website, such as when users land on a page coming from an external resource like a search engine or if page changes happen unexpectedly or unannounced. That’s especially true for single-page applications (SPAs), where page navigation works differently from most sites.

The page’s title is one of the essential elements in an HTML document, and users benefit from a well-formed and descriptive page title.

Screen reader users can use shortcuts to announce the page title. For example, if they click a link in an SPA and content changes, but there’s no announcement that changes have happened, they can use a shortcut to get oriented and check if they’ve landed on a different page. You can try it yourself by using one of the shortcuts in Table 1-1.

Table 1-1. Different ways to announce the page title with screen readers.
Screen reader Command Announcement

JAWS

Ins + T

Page title

NVDA

Ins + T

Page title

VoiceOver macOS

VO + Shift + I

Page summary, including page title

VoiceOver macOS

VO + F

Page title

Note

By default, VO stands for the combination of pressing Control and Option at the same time in VoiceOver on macOS. Alternatively, you can map VO to Caps Lock in the VoiceOver Utility settings.

There are other reasons for writing good page titles: they serve as labels for bookmarked pages/favorites, and search engines use the title in their results pages. Social media sites, chat and mail applications, and similar software use the title in link previews when no other title is specified. Please note that the open graph meta tag shown in Example 1-16 is no alternative to the <title> element. Whether a site or application interprets the open graph title is up to the site. Ideally, the native title’s content should be good enough to serve all purposes.

There are several best practices you should follow when writing page titles:

The title must be unique

The <title> serves as the label in tabs or browser windows. Unique titles help to distinguish one page from the other if multiple tabs of the same site are open. A common issue is that the title is the same on all pages (see Example 1-21). The result is shown in Figure 1-1.

Example 1-21. Bad practice: Three different pages with the same title
<!-- products.html -->
<title>Johanna’s Toy Store</title>

<!-- team.html -->
<title>Johanna’s Toy Store</title>

<!-- contact.html -->
<title>Johanna’s Toy Store</title>
All tabs are labeled “Johanna’s Toy Store”.
Figure 1-1. It’s impossible to tell these pages apart by looking at the tabs

Use unique titles to communicate the purpose of the page and improve orientation (see Example 1-22 and the result in Figure 1-2).

Example 1-22. Three different pages, each with a unique title
<!-- products.html -->
<title>Products - Johanna’s Toy Store</title>

<!-- team.html -->
<title>Our Team - Johanna’s Toy Store</title>

<!-- contact.html -->
<title>Get in Touch - Johanna’s Toy Store</title>
3 tabs labeled Products, Our Team, and Get in Touch.
Figure 1-2. By looking at the tabs, you can tell what each page is about

That applies to websites with multiple pages but also to SPAs. You might have to take extra steps in an SPA, but if the user navigates to a different route, the page title must change as well. Hidde De Vries explains how to do that in “Accessible page titles in a Single Page App”.

The title should be concise

The title should be concise and should accurately describe the purpose of the page. It’s the first information a screen reader user gets when they’re accessing a page. They don’t need a detailed summary of the page’s content, but a succinct description.

Another reason to constrain the length of the title is that it usually gets cut off in search result pages at a certain character length (approximately 50 to 60 characters).

The title should be descriptive

When you title a page, do it with the user in mind. While SEO is important, the user experience is much more important. The title should describe the page’s purpose and must not include marketing or SEO terms solely to improve page rankings.

The relevant information comes first

The title should start with the page’s name, followed by the name of the site, company, or organization, as shown in Example 1-15. Putting the relevant information first reduces repetition for screen reader users who visit multiple pages on a site, because they get the unique page-specific details first. This way of arranging content makes scanning and identifying pages easier when numerous tabs are open, as shown in Figure 1-3.

3 tabs labeled Products, Our Team, and Get in Touch. Each has a suffix “- Johanna’s Toy Store”.
Figure 1-3. The name of the page is the first information in the browser’s tab

Don’t put the organization’s name first (as in Example 1-23) because the relevant information might get cut off, as you can see in Figure 1-4.

Example 1-23. Bad practice: Name of the site followed by the name of the page
<title>Johanna’s Toy Store - Products</title>
3 tabs labeled Products, Our Team, and Get in Touch. Each has a prefix “Johanna’s Toy Store - ”.
Figure 1-4. With the name of the site as the first information in the browser’s tab, in some cases the name of the page is cut off

Context-dependent information

Sometimes it’s helpful to add context or additional information. For example, if you split a page into multiple steps, the title should include the current step. Example 1-17 shows the title of the third of four steps in a checkout process. If there are validation errors in a form, you can indicate the number of errors (see Example 1-18). For search result pages, you can add the number of results or the current page, as shown in Examples 1-19 and 1-20.

1.3 Set the Viewport Width

Problem

Sometimes users want to zoom into a page because they can’t read the text or want a closer look at something. They can’t do that if the viewport settings prohibit zooming. That is especially problematic for people with low vision.

Solution

Configure the viewport meta tag in a way that allows for the most flexibility. Avoid restrictive settings.

The meta tag in Example 1-24 works for most websites and web apps. It’s all you need to configure viewport settings to build a flexible, adaptive, responsive website.

Example 1-24. The page uses the available width of the device as the width for the viewport
<meta name="viewport" content="width=device-width, initial-scale=1">

There are specific properties or values you should avoid.

Setting the value of the width property to anything other than device-width can cause problems. If the defined width of the viewport is larger than the available width on the screen, content may overflow, resulting in horizontal scroll bars. Example 1-25 applies an explicit viewport width.

Example 1-25. Bad practice: Width of the viewport set to an absolute value
<meta name="viewport" content="width=500, initial-scale=1">

maximum-scale allows you to limit the maximum zoom level, which is 10 by default in most browsers. If you set it to 1, you’re disabling zoom in some browsers (see Example 1-26).

Example 1-26. Bad practice: Zoom disabled by setting the maximum scale to 1
<meta name="viewport" content="width=device-width, maximum-scale=1, initial-scale=1">

The setting user-scalable defines whether zooming is allowed. Setting it to no or 0 disables zoom, as shown in Example 1-27.

Example 1-27. Bad practice: Zoom disabled by setting user-scalable to “no”
<meta name="viewport"
      content="width=device-width, user-scalable=no, initial-scale=1">

Discussion

Users must be able to customize their browsing experience based on their preferences and needs. Browsers offer different settings and features to support that. The ability to set larger font sizes or zoom in on the page is essential, but many websites disallow zooming on handheld devices.

Before responsive web design became a thing, websites were designed for large viewports, often using fixed width values like 960px or 1024px for the body or main content of the page. With the rise of smartphones and other handheld devices, this became a problem because pixel widths of the screens on these devices were usually much smaller than 960px. The initial containing block, the rectangle in which the root element (<html>) lives, has the dimensions of the viewport. If the page is larger than the viewport, this can result in unintended layout wrapping, clipped content, and unpleasant scrollable bounds. That’s why mobile browsers generally use a fixed width (typically 980px to 1024px) for the initial containing block. The resulting layout is then scaled down to fit the available screen space. That mitigates the issues, but it also means that the CSS pixel size on these pages will be much smaller, forcing users to zoom in.

On responsive websites, that’s not an issue, since they’ve been built to work well on assorted viewports. However, you have to change the fixed width of the containing block on mobile devices to a width relative to the viewport’s dimensions to work well with responsive designs. You can do that by using the viewport meta tag, as illustrated in Example 1-24.

width=device-width sets the viewport’s width to the device’s available width.

initial-scale=1 ensures that the default zoom level is at 100%. This might not always be the default in all browsers. That’s why I recommend setting it explicitly.

The fact that a page is responsive and optimized for small viewports doesn’t mean users won’t want to zoom. Adrian Roselli lists several reasons the ability to zoom is essential in his article “Don’t Disable Zoom”:

  • The text may be too small for the user to read.

  • The user may want to see more detail in an image.

  • Selecting words to copy/paste may be easier for users when the text is larger.

  • The user wants to crop animated elements out of the view to reduce distraction.

  • The developer did a poor job of responsive design, and the user needs to zoom just to use the page.

  • There is a browser bug that causes the default zoom level to be odd.

  • It can be confounding for users when the browser interprets a pinch/spread gesture as something else.

Websites disabling zoom is a prevalent issue. According to the Accessibility chapter of the 2022 Web Almanac, 23% of desktop home pages and 28% of mobile home pages attempt to disable zoom. The report’s author uses the term attempt, because some browsers, like Safari on iOS or Samsung Internet on Android, ignore the maximum-scale=1 and user-scalable=no properties. Chrome and Firefox don’t, but users can force zoom in their browser settings. In Firefox, find the browser settings, select “Accessibility,” and activate “Zoom on all websites.” In Chrome, find the browser settings, select “Accessibility,” and check “Force enable zoom.”

Justified reasons to disable zoom

On the average website, there’s no good reason to turn off zoom. The same applies for app-like websites that resemble native apps. There are rare exceptions where the gestures for zooming would interfere with the website’s functionality. An example would be a site that contains only an interactive map. If that’s the case, it might be okay to disable the native zoom feature, but you must provide an alternative custom solution.

1.4 Optimize Rendering Order

Problem

The head of a document can contain various elements that serve different purposes: meta tags, scripts, links to other resources, and more. They can be in any order, but certain elements should come before others to ensure good loading performance. Inefficient asset loading prevents users from obtaining information quickly, if at all.

Solution

Web performance expert Harry Roberts suggests a specific order of elements within the <head> to ensure the best possible loading strategy, as shown in Example 1-28.

Example 1-28. The ideal order of elements in the <head>
<head>
  <!-- Character encoding -->
  <meta charset="UTF-8">

  <!-- Viewport meta tag -->
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <!-- CSP headers -->
  <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

  <!-- Page title -->
  <title>Johanna’s Toy Store</title>

  <!-- preconnect -->
  <link rel="preconnect" href="#" />

  <!-- Asynchronous JavaScript -->
  <script src="" async></script>

  <!-- CSS that includes @import -->
  <style>
    @import "file.css";
  </style>

  <!-- Synchronous JavaScript -->
  <script src=""></script>

  <!-- Synchronous CSS -->
  <link rel="stylesheet" href="#">

  <!-- preload -->
  <link rel="preload" href="#" />

  <!-- Deferred JavaScript -->
  <script src="" defer></script>
  <script src="" type="module"></script>

  <!-- prefetch / prerender -->
  <link rel="prefetch" href="#" />
  <link rel="prerender" href="#" />

  <!-- Everything else (meta tags, icons, open graphs, etc.) -->
  <meta name="description" content="">
</head>

Discussion

There are different fields within web design and development, like accessibility, usability, user experience, performance, and security. They all focus on different things, but they’re not mutually exclusive. Accessibility, for example, overlaps with all of them. Improving the accessibility of form fields may result in a better user experience for everyone. If a website loads slowly, it affects users’ experience and accessibility. A website that loads for too long or not at all on a slow connection is not accessible. Designing and building accessible websites means creating inclusive experiences without barriers that prevent people from interacting with the web. These barriers include physical, temporary, and situational disabilities and socioeconomic restrictions on hardware, bandwidth, and speed.

Getting the order of elements in the <head> right affects performance in general, but it also affects the rendering of specific elements that may contain critical information for users of assistive technology. HTML is parsed line by line, which means that a browser doesn’t know that line 4 exists when line 3 hasn’t finished parsing. If something blocks rendering early in a document, subsequent lines have to wait until the browser has finished parsing preceding lines. That makes the correct order of elements in the <head> crucial to web performance and accessibility.

Performance experts suggest several rules and optimizations, including:

  • If something doesn’t have to be in the <head>, remove it or put it in the <body>. That includes low-priority scripts, redirects, or any unnecessary payload.

  • Self-host as much as possible and don’t rely on third-party content delivery networks (CDNs). Harry Roberts explains why in his article “Self-Host Your Static Assets”.

  • Validate your HTML code, because invalid elements in the <head> can cause performance problems.

  • Metadata about the page, like character encoding and information about the viewport, go first.

  • Nothing render-blocking must come before the <title>.

  • Synchronous JavaScript comes before CSS, because CSS blocks the execution of subsequent JavaScript.

  • Avoid @import in CSS.

  • SEO and social meta tags go last.

Harry Roberts has created a CSS file called ct.css, also available as a bookmarklet, that you can use to run tests against your <head> elements (see Figure 1-5).

A list of messages, each with a thick border with different styles and colors indicating a success, warning or error.
Figure 1-5. ct.css displaying messages on a page after running tests

1.5 Structure the Document

Problem

If a page doesn’t contain enough semantic regions, users might not be able to understand how it’s structured. That lack of semantic markup prevents them from using shortcuts to navigate more efficiently.

Solution

Use landmarks: regions that represent the organization and structure of a web page. They usually identify areas the user may want to access quickly.

Chapter 2, “Structuring Pages” focuses on page regions, but there are also common landmarks you will use across your site, like <header>, <main>, and <footer>. Every element in the page should be within one of these landmarks, as shown in Example 1-29.

Example 1-29. An exemplary structure of a web page
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>Products - Johanna’s Toy Store</title>
</head>
<body>
  <header> 1
    <a href="/">
      Johanna’s Toy Store
    </a>

    <nav aria-label="Main"> 2
      <ul>
        <li>
          <a href="/home">Home</a>
        </li>
        <li>
          <a href="/products" aria-current="page">Products</a>
        </li>
        <li>
          <a href="/team">Team</a>
        </li>
        <li>
          <a href="/contact">Contact</a>
        </li>
      </ul>
    </nav>

    <form role="search"> 3
      <label for="search">Search</label>
      <input type="text" id="search">
    </form>
  </header>

  <main id="content"> 4
    <h1>All products</h1>

  </main>

  <footer> 5
    &copy; 2024
  </footer>
</body>
</html>
1

The header of the site (banner landmark).

2

The main navigation (navigation landmark).

3

The site search (search landmark).

4

The main content (main landmark).

5

The footer of the site (contentinfo landmark).

Discussion

Using semantic elements within components and regions of a page is the foundation of any accessible website, but users can benefit from larger semantic groups, too. The page must communicate how it’s structured and group common sitewide and page-specific elements. Landmarks in HTML help with that.

You can define landmarks with the appropriate HTML elements or use the role attribute when no element exists. The elements in Example 1-30 are semantically the same.

Example 1-30. Two banner landmarks
<!-- <header> with an implicit banner role -->
<header></header>

<!-- <div> with an explicit banner role -->
<div role="banner"></div>
Tip

Most semantic elements in HTML convey two bits of information: their accessible role and an accessible name. The role defines what kind of element it is: a button, link, image, etc. The accessible name is text by which software can identify a component, coming from the element’s text content, another associated element like <label>, or an attribute like aria-label, aria-labelledby, alt, or title.

Follow the first rule of Accessible Rich Internet Application (ARIA) use and prefer elements with implicit roles over using the role attribute if browser support allows it. Older browsers and screen readers that don’t support elements with implicit landmark roles once needed the additional explicit role, as shown in Example 1-31, but specifying both isn’t necessary anymore.

Example 1-31. <header> with an additional explicit banner role
<header role="banner"></header>

There are different types of regions that serve other purposes in different contexts. Table 1-2 lists HTML elements, their corresponding ARIA roles, and the context in which they’re exposed as landmarks.

Table 1-2. HTML landmarks and their ARIA roles
Element ARIA role Conditions

header

banner

Only in context of the body element; not when it’s a descendant of <article>, <aside>, <main>, <nav>, or <section> (or any other element with their corresponding explicit roles).

nav

navigation

main

main

section

region

When it has an accessible name.

form

form

When it has an accessible name.

search

search

Or form with role="search".

aside

complementary

footer

contentinfo

Only in context of the body element; not when it’s a descendant of <article>, <aside>, <main>, <nav>, or <section> (or any other element with their corresponding explicit roles).

Benefits

There are many reasons to use landmarks. The remainder of this section will explain several of those reasons in detail.

Orientation

Landmarks help screen reader users with orientation on the page. The software may announce landmarks when users enter or leave the enclosed content. They contain every item on the page to help users discover them.

Navigation

Screen reader users can jump from landmark to landmark using keyboard shortcuts or gestures, which provide a convenient way to skip to specific areas without interacting with the rest of the page (see Table 1-3).

In VoiceOver on iOS, you can select the “landmark” option in the rotor, which provides you with direct access to certain elements on the page, and use the swipe up and down gestures to navigate between landmarks. In TalkBack on Android, you can set the reading controls to “landmarks” and swipe up and down to navigate. In NVDA on Windows, you can press D or Shift + D, and in JAWS on Windows, R and Shift + R to do the same (see Table 1-3).

Table 1-3. Landmark navigation shortcuts
Screen reader Command

NVDA

D

JAWS

R

Narrator

D

VoiceOver on iOS

Rotor

TalkBack on Android

Reading controls

It’s mostly screen reader users who benefit from having landmarks, but also browser extensions like “Landmark Navigation via Keyboard or Pop-up” add keyboard shortcuts to the browser, providing access to landmarks for non-screen reader users. See Figure 1-6.

Overview

Screen reader users can list all landmarks on a page and access them directly (see Table 1-4).

Table 1-4. Shortcuts for listing all kinds of elements, such as landmarks
Screen reader Command

NVDA

Ins + F7

JAWS

Ins + Ctrl + R

VoiceOver on macOS

Rotor

A pink outline around the main element and a label “main” in the top right corner.
Figure 1-6. The main landmark on handbuch.wien.gv.at, highlighted by the “Landmark Navigation” browser extension

Site-Specific Landmarks

The three most relevant main landmarks are <header>, <main>, and <footer>.

banner landmark

The <header>, with its implicit banner role, contains mostly site-oriented rather than page-specific content. That’s typically a logo, skip links, the main navigation, secondary navigations, a search widget, and other content that is relevant and visible on every page.

Not every <header> is a landmark. If it’s nested inside <article>, <aside>, <main>, <nav>, or <section>, it’s semantically similar to a <div> and not exposed as a landmark anymore. Having multiple header elements on a page is fine, but you should add only a single banner landmark.

Typically, you’ll find banner landmarks at the beginning of the <body> in the document. Visually, it’s usually at the top of the page. That is a common pattern but not a strict rule; it may also look like a sidebar. The position doesn’t affect its semantic purpose. Just because it’s located on the side doesn’t mean its role has to change.

main landmark

The <main> element’s implicit main role represents the page’s core content. There should be only one visible main element on a page, and its ancestors should be limited to html and body to guarantee a hierarchically correct structure. If necessary, it’s possible to wrap it in <div> elements.

If you’re working with an SPA with multiple <main> elements on a page, hide all the inactive ones, as shown in Example 1-32. Having more than one visible and reachable main landmark on a page might confuse users and result in them missing content because they usually expect only one per page.

Example 1-32. Multiple main elements, but only one is visible
<main hidden>
  <h1>Home</h1>
</main>
<main>
  <h1>Products</h1>
</main>
<main hidden>
  <h1>Team</h1>
</main>
<main hidden>
  <h1>Contact</h1>
</main>

contentinfo landmark

The <footer> element’s implicit contentinfo role also contains site-oriented content. That’s typically copyright data, secondary navigations, and other links.

Similar to the <header>, the <footer> is only a landmark in the <body> context. If it’s nested inside <article>, <aside>, <main>, <nav>, or <section>, it’s not a landmark anymore. Having multiple footer elements on a page is fine, but you should add only a single contentinfo landmark.

Get Web Accessibility Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.