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
Accessibilities trees
The Optimal Outline Size
button
should:
- Be focusable via the keyboard
- Support being disabled
- Support the
ENTER
orSPACE
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
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 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.Links
Not descriptive enough
Useful content!
Section
iFrames
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.
Form
- Place the input element inside of a label element
- Or use the label's
for
attribute and refer to the element'sid
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:Provide more information to user about a field
Provide error messages
We can set the attributes of the input like
required
type
Every HTML element will have some of the following semantic properties:
- A role or type
- A name
- A value (optional)
- A 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”
: focusabletabindex="-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.
Roles define what an element is or does on the page or app.
Self-destruct
States/values define the current conditions or data values associated with the element.
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.
- Use
aria-pressed
to indicate that a button has been pressed
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.
- Some live packages for common JavaScript frameworks:
- React: react-aria-live and react-a11y-announcer
- Angular:
LiveAnnouncer
- Vue: vue-a11y-utils
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."
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
NickColley • Updated Oct 14, 2024