Accessibility
📔

Accessibility

Focusable elements

The following HTML elements are keyboard navigable: button, a, input, summary, textarea, select, and the controls of elements audio and video (when the controls attribute is added). Additionally, certain attributes such as contenteditable or tabindex can make an element keyboard navigable. In the case of Firefox, any area with a scroll will also be keyboard focusable.

Overview

HTML
<header>
   <h1>Three words</h1>
    <nav>
      <a>one word</a>
      <a>one word</a>
      <a>one word</a>
      <a>one word</a>
    </nav>
</header>
<main>
  <header>
    <h1>five words</h1>
  </header>
  <section>
   <h2>three words</h2>
   <p>forty-six words</p>
   <p>forty-four words</p>
  </section>
  <section>
   <h2>seven words</h2>
   <p>sixty-eight words</p>
   <p>forty-four words</p>
  </section>
</main>
<footer>
   <p>five words</p>
</footer>

Accessibilities trees

FireFox
FireFox
Chrome
Chrome
 
The Optimal Outline Size
CSS
/* Add more selectors inside the :is rule if needed */
:is(a, button, input, textarea, summary) {
    --outline-size: max(2px, 0.08em);
    --outline-style: solid;
    --outline-color: currentColor;
}

:is(a, button, input, textarea, summary):focus {
    outline:
      var(--outline-size)
      var(--outline-style)
      var(--outline-color);
    outline-offset: var(--outline-offset, var(--outline-size));
}

@supports selector(:focus-visible) {
  *:focus {
      outline: none
  }

  *:focus-visible {
      outline:
        var(--outline-size)
        var(--outline-style)
        var(--outline-color);
      outline-offset: var(--outline-offset, var(--outline-size));
  }
}

button should:

  • Be focusable via the keyboard
  • Support being disabled
  • Support the ENTER or SPACE keys to perform an action
  • Be announced properly by a screen reader
 
icon buttons
It can be helpful to give them an explicit accessible name using the aria-label attribute.
or
HTML
<button>
  <svg class="icon">
    <use xlink:href="#icon-1" />
  </svg>
  <span class="tooltip hidden">Open menu</span>
</button>
Yes. Even if the button's tooltip is visually hidden using CSS, assistive technologies can still read its text content.
Caution: When visually hiding button text, use CSS rather than the hidden attribute. The hidden attribute removes the element from the accessibility tree.

nav

use aria-current=’page’ in the nav bar
HTML
<nav aria-label="Breadcrumb">
  <ol>
    <li>
      <a href="../../">
        ARIA States and Properties
      </a>
    </li>
    <li>
      <a href="./" aria-current="page">
        ARIA: `aria-current` attribute
      </a>
    </li>
  </ol>
</nav>
 

img should:

Always be accompanied by an alt attribute to give the image its accessible name.

For decorative images,

many screen readers announce the whole image URL if no alt is provided,
use the aria role attribute role="presentation" as this also stops screen readers from reading out alternative text.
HTML
<img src="dinosaur.png" aria-labelledby="dino-label">
<p id="dino-label">The Mozilla red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth.</p>
 
HTML
<figure>
  <img src="dinosaur.png" alt="The Mozilla Tyrannosaurus">
  <figcaption>A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth.</figcaption>
</figure>

Links

Not descriptive enough
HTML
Check out our guide to web performance <a href="/guide">here</a>.
Useful content!
HTML
Check out <a href="/guide">our guide to web performance</a>.

Section

HTML
<header>
	<nav>...</nav>
</header>
<main>
	<section aria-label="Introduction to stamp collecting">
    <p>Stamp collecting, also known as philately, is
    the study of postage stamps, stamped envelopes,
    postmarks, postcards, and other materials relating
    to postal delivery.</p>
	</section>
</main>
<footer>
	<p>© 2022 - Stamps R Awesome</p>
</footer>
 
HTML
<header>
  <h1>Stamp Collecting</h1>
</header>
<main>
	<section aria-label="Introduction to Stamp Collecting">
		<h2>What is Stamp Collecting?</h2>
		<p>Stamp collecting, also known as philately, is the study of postage stamps, stamped envelopes, postmarks, postcards, and other materials related to postal delivery.</p>
	</section>

	<section aria-label="Starting a Stamp Collection">
		<h2>How to Start a Stamp Collection</h2>
    <h3>Required Equipment</h3>
    <p>...</p>

    <h3>Acquiring Stamps</h3>
    <p>...</p>

    <h3>Joining Organizations</h3>
		<p>...</p>
	</section>
</main>

iFrames

HTML
<iframe title="Google Pixel - Lizzo in Real Tone"
  src="https://www.youtube.com/embed/3obixhGZ5ds"
  scrolling="auto">
</iframe>

Focus outline

Adhere to a 3:1 color contrast ratio for all focus indicators. There is no rule about the number of focus indicator styles to have on one page; however, keep it reasonable to avoid confusion.
CSS
a:focus {
  outline: auto 5px Highlight; /* for non-webkit browsers */
  outline: auto 5px -webkit-focus-ring-color; /* for webkit browsers */
}

Form

  • Place the input element inside of a label element
HTML
<label>
  <input type="checkbox">Receive promotional offers?</input>
</label>
  • Or use the label's for attribute and refer to the element's id
HTML
<input id="promo" type="checkbox"></input>
<label for="promo">Receive promotional offers?</label>
if an <input type="image"> element is used to create an image button, it should contain alt text that describes the action that occurs when the user clicks on the button:
HTML
<form>
  <label>
    Username:
    <input type="text">
  </label>
	<input type="image"alt="Sign in" src="./sign-in-button.png">
</form>
Provide more information to user about a field
HTML
<form>
	<div>
		<label aria-describedby="name-description" for="promo">Name</label>
		<input id="promo" type="text" />
		<p id="name-description">Your surname and family name</p>
	</div>
</form>
Provide error messages
HTML
<p>
  <label for="email">Email address:</label>
  <input
    type="email"
    name="email"
    id="email"
    aria-invalid="true"
    aria-errormessage="err1" />
  <span id="err1" class="errormessage">Error: Enter a valid email address</span>
</p>
We can set the attributes of the input like required type
 
Every HTML element will have some of the following semantic properties:
  • role or type
  • name
  • value (optional)
  • state (optional)
An element's name  is its computed label. Screen readers typically announce an element's name followed by its role, e.g. "Sign Up, button."
Some elements may have a value For instance, <input type="text"> may have a value that reflects whatever the user has typed into the text field.
 
Some elements may also have a state, which conveys their current status. For instance, a <select> element can be in either an expanded or a collapsed state, depending on if it's open or closed.
 
synthetic click activation If you add a "click" handler to a button, it will run when the user presses ENTER or SPACE
 
tabindex="0”: focusable
tabindex="-1”: not focusable by tab but can use JS.
 

Skip to the main

Help keyboard users quickly navigate long navigation menus by allowing them to skip over redundant or unuseful groups of links. This is especially helpful for users who have already visited the page of interest.
HTML
/* style.css */
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: #000000;
  color: white;
  padding: 8px;
  z-index: 100;
}

.skip-link:focus {
  top: 0;
}

<!-- index.html -->
<a class="skip-link" href="#main">Skip to main</a>
…
<main id="main">
  [Main content]
</main>
 
HTML
<header>
  <h1>Header</h1>
</header>

<nav>
  <!-- main navigation in here -->
</nav>

<!-- Here is our page's main content -->
<main>

  <!-- It contains an article -->
  <article>
    <h2>Article heading</h2>

    <!-- article content in here -->
  </article>

  <aside>
    <h2>Related</h2>

    <!-- aside content in here -->
  </aside>

</main>

<!-- And here is our main footer that is used across all the pages of our website -->

<footer>
  <!-- footer content in here -->
</footer>
 
Roles define what an element is or does on the page or app.
HTML
<div role="button">Self-destruct</div>
Self-destruct
HTML
<div role="button" aria-describedby="more-info">Self-destruct</div>
<div id="more-info">This page will self-destruct in 10 seconds.</div>
States/values define the current conditions or data values associated with the element.
HTML
<div role="button" aria-describedby="more-info" aria-pressed="false">
  Self-destruct
</div>

<div id="more-info">
  This page will self-destruct in 10 seconds.
</div>

Focus management

Component level - A keyboard trap is a situation where a user who is only using a keyboard is unable to navigate away from a particular component, or the focus is not maintained when it should be.
Page level  - Focus must also be maintained when a user navigates from page-to-page.
  • Place focus on the main container with an aria-live announcement.
  • Put the focus back to a link to skip to the main content.
  • Move the focus to the top-level heading of the new page.

State management

Component level - e.g.
  • Use an aria-expanded attribute to tell the user whether a drop-down menu or list is expanded or collapsed.
Page level -
  • Developers often use a visually hidden area called the ARIA live region to announce changes on the screen and alert messages to assistive technology (AT) users.
 

ARIA

Live regions

Can be used to show the errors or staus from inputs in form, announce the current time, show alerts and indicate the progress of progressbar.

Reference

Five rules of ARIA to help making elements accessible.

Rule 1: Don't use ARIA 

Yes, you read that right. Adding ARIA to an element does not inherently make it more accessible. The WebAIM Million annual accessibility report found that home pages with ARIA present averaged 70% more detected errors than those without ARIA, primarily due to the improper implementation of the ARIA attributes.
There are exceptions to this rule. ARIA is required when an HTML element doesn't have accessibility support. This could be because the design doesn't allow for a specific HTML element or the wanted feature/behavior isn't available in HTML. However, these situations should be scarce.
Don't <a role="button">Submit</a> Do <button>Submit</button>
When in doubt, use semantic HTML elements.

Rule 2: Don't add (unnecessary) ARIA to HTML 

In most circumstances, HTML elements work well out of the box and do not need additional ARIA added to them. In fact, developers using ARIA often have to add additional code to make the elements functional in the case of interactive elements.
Don't <h2 role="tab">Heading tab</h2> Do <div role="tab"><h2>Heading tab</h2></div>
Do less work and have better-performing code when you use HTML elements as intended.

Rule 3: Always support keyboard navigation 

All interactive (not disabled) ARIA controls must be keyboard accessible. You can add tabindex= "0" to any element that needs a focus that doesn't normally receive keyboard focus. Avoid using tab indexes with positive integers whenever possible to prevent potential keyboard focus order issues.
Don't <span role="button" tabindex="1">Submit</span> Do <span role="button" tabindex="0">Submit</span>Of course, if you can, use a real <button> element in this case.
CautionRemember, people with and without visual impairments use keyboard navigation. Don't add unnecessary tab stops to headings and paragraphs, as these can add additional challenges for some users who navigate by keyboard alone.

Rule 4: Don't hide focusable elements 

Don't add role= "presentation" or aria-hidden= "true" to elements that need to have focus—including elements with a tabindex= "0". When you add these roles/states to elements, it sends a message to the AT that these elements are not important and to skip over them. This can lead to confusion or disrupt users attempting to interact with an element.
Don't <div aria-hidden="true"><button>Submit</button></div> Do <div><button>Submit</button></div>

Rule 5: Use accessible names for interactive elements

The purpose of an interactive element needs to be conveyed to a user before they know how to interact with it. Ensure that all elements have an accessible name for people using AT devices.
Accessible names can be the content surrounded by an element (in the case of an <a>), alternative text, or a label.
For each of the following code samples, the accessible name is "Red leather boots."
HTML
<!-- A plain link with text between the link tags. -->
<a href="shoes.html">Red leather boots</a>

<!-- A linked image, where the image has alt text. -->
<a href="shoes.html"><img src="shoes.png" alt="Red leather boots"></a>

<!-- A checkbox input with a label. -->
<input type="checkbox" id="shoes">
<label for="shoes">Red leather boots</label>
There are many ways to check an element's accessible name, including inspecting the accessibility tree using Chrome DevTools or testing it with a screen reader.
Coming soon: read more about screen reader testing in the Assistive Technology module.

The current support of HTML accessibility

HTML to ARIA landmark elements

HTML landmark element
ARIA landmark role

Tools

jest-axe
NickColleyUpdated Oct 14, 2024
 

Reference