Good accessibility or "a11y" is crucial to making sure all users can access the content in your sites and applications. Making sure you consider accessibility at the start of your process will ensure that your final product is more polished and works for more people.
Note: We often shorten the word "accessibility" to "a11y" because there are 11 letters between the "A" and "Y" in the word "Accessibility". Sometimes you'll see this pattern used in other contexts like i18n for "internationalization" and l10n for "localization".
Some statistics on disability for the US:
- Around 2% of the population has some kind of vision disability (i.e. are blind or have significant difficulty seeing even with glasses)
- Around 50% of the population has some kind of clinically significant refractive error (a visual impairment which may be corrected with glasses if mild enough)
- Around 8% of males and 0.5% of females have some form of color vision deficiency
- Around 2% of adults have a hearing disability
- Over 4% have a cognitive disability (difficulty remembering, concentrating, or making decisions)
Sources:
- Disability Compendium
- "The Perception of Color"
- "Prevalence of Refractive Error in the United States, 1999-2004"
Checklists:
WebAIM checklist items:
Move focus around the page using your keyboard:
TAB
will move focus forwardSHIFT - TAB
will move focus backwardsArrow keys
can be used to navigate inside of a component- https://html.spec.whatwg.org/multipage/interaction.html#focus-management
WebAIM checklist items:
tabindex
on MDN
We should typically only add tabindex
attributes to interactive elements, and not to our site content. With this in mind, consider a web page that looks like the following:
Solution
You can read more about skip links in this article on the Web AIM site.
https://developers.google.com/web/updates/2016/03/focus-start-point?hl=en
Take a look at the ARIA Authoring Best Practices guide to read more about the Radio pattern.
ARIA Authoring Best Practices (Radio Group)
To find your missing focus you can type the following into your console:
document.activeElement
Read more about Document.activeElement on MDN
WebAIM checklist items:
<dialog>
on MDN
Matching a Simple DOM and A11y Tree
For example:
<!-- bad -->
<input type="radio" checked name="tType" value="0">
<!-- good -->
<label>
<input type="radio" checked name="tType" value="0">
Round Trip
</label>
<!-- good -->
<input type="radio" checked name="tType" value="0" id="round-trip">
<label for="round-trip">Round Trip</label>
WebAIM Guideline 1.1: http://webaim.org/standards/wcag/checklist#g1.1
The MDN page on <label>
demonstrates the two options for associating a <label>
with the thing it's labelling.
The W3C spec has a list of what types of elements work with a <label>
tag.
WebAIM checklist items:
- 1.3.2: http://webaim.org/standards/wcag/checklist#sc1.3.2
- 2.4.10: http://webaim.org/standards/wcag/checklist#sc2.4.10
- 1.3.1: http://webaim.org/standards/wcag/checklist#sc1.3.1
- 2.4.1: http://webaim.org/standards/wcag/checklist#sc2.4.1
- 2.4.6: http://webaim.org/standards/wcag/checklist#sc2.4.6
JavaScript headings snippet:
const hs = document.querySelectorAll('h1,h2,h3,h4,h5,h6');
for (let i = 0; i < hs.length; i++) {
console.log(hs[i].textContent.trim() + " " +
hs[i].tagName,
hs[i]);
}
For each of the labeled portions of the page, provide some alternate text where necessary, and a blank alt attribute otherwise.
A: alt="shopping cart" B: alt="koala munchies" C: alt="" D: alt="cider gum" E: alt=""
Shortcuts mentioned:
CMD
+F5
to turn on VoiceOver on OS X Normal keyboard operation (TAB
,Shift
+TAB
, arrow keys etc.) work as normal with VoiceOver runningCMD
+L
to jump to address barCTRL
+Option
+U
to open Web Rotor Type search term with Web Rotor open to search within Web RotorCTRL
+Option
+←
↑
↓
→
to explore contentCTRL
+Option
+CMD
+H
to move forward by headingCTRL
+Option
+CMD
+Shift
+H
to move backward by heading
WebAIM's article on Using VoiceOver to evaluate Web Accessibility has a full introduction to VoiceOver from the point of view of evaluating accessibility, including most keyboard commands available.
If you don't have a Mac device, NVDA is a free, open source screen reader available for Windows. WebAIM's introduction to NVDA covers the basics of using NVDA to check accessibility.
If you only use Linux, Orca is available in the Gnome desktop manager, although this screen reader is much more rarely used and suffers from poor support by web browsers.
WebAIM checklist items:
- 1.3.2: http://webaim.org/standards/wcag/checklist#sc1.3.2
- 2.4.10: http://webaim.org/standards/wcag/checklist#sc2.4.10
- 1.3.1: http://webaim.org/standards/wcag/checklist#sc1.3.1
- 2.4.1: http://webaim.org/standards/wcag/checklist#sc2.4.1
- 2.4.6: http://webaim.org/standards/wcag/checklist#sc2.4.6
JavaScript headings snippet:
for (let i = 0, headings = $$('h1,h2,h3,h4,h5,h6');
i < headings.length; i++) {
console.log(headings[i].textContent.trim() + " " +
headings[i].tagName,
headings[i]);
}
Shortcuts mentioned:
CTRL
+Option
+U
to open Web Rotor←
and→
to change panes within Web Rotor- Type search term with Web Rotor open to search within Web Rotor
- Enter to move VoiceOver focus to item from Web Rotor
CTRL
+Option
+Spacebar
to activate link/button/other elementCTRL
+Option
+←
↑
↓
→
to explore contentCTRL
+Option
+CMD
+H
to move forward by headingCTRL
+Option
+CMD
+Shift
+H
to move backward by headingCTRL
+Option
+W
to have a word spelled out
WebAIM's article on accesskey
: http://webaim.org/techniques/keyboard/accesskey
WebAIM's articles on VoiceOver and NVDA:
WebAIM checklist item 2.4.9: http://webaim.org/standards/wcag/checklist#sc2.4.9
ARIA 1.0 roles: https://www.w3.org/TR/wai-aria-1.0/#roles
ARIA 1.1 roles (draft): https://www.w3.org/TR/wai-aria-1.1/#roles
ARIA 1.1 practices guide (draft): https://www.w3.org/TR/wai-aria-practices-1.1/
We've covered several ways to label elements already, and we just learned about two more: aria-label
, and aria-labelledby
.
For this exercise, we're going to see some of those labeling techniques in action! We'll put our skills to the test by figuring out the accessible name for a few elements.
Instructions In each case, provide the label for the first (i.e., outermost) element. If the element would be hidden from the accessibility tree, type in No label as your answer. Note that HTML labelling techniques, and ARIA roles and attributes, must be used correctly in order to be effective!
Question 1:
<button aria-lavbel="Gumnut">
Eucalyptus
</button>
Answer
Answer: Gumnut
Question 2:
<div role="button">
Wombat
</div>
Answer
Answer: Wombat
Question 3:
<input type="checkbox" name="roo">
<label for="roo">
Kangaroo
</label>
Answer
Answer: No label
Question 4:
<span role="checkbox"
aria-checked="false"
aria-labelledby="label"
aria-label="Not checked"></span>
<span id="label">Wallaby</span>
Answer
Answer: Wallaby
ARIA in HTML spec, including guidance on what ARIA roles may and may not be used with which HTML elements: https://www.w3.org/TR/html-aria/
Hidden In Plain Sight
For more information on screen reader-only text, check out WebAIM's article on "invisible content".
In each case, provide the label for the first (i.e., outermost) element. If the element would be hidden from the accessibility tree, type in No label as your answer. Note that HTML labelling techniques, and ARIA roles and attributes, must be used correctly in order to be effective!
Here are some resources that may help you along the way:
aria-hidden
definition- HTML5
hidden
definition aria-labelledby
definition- Recall that
aria-labelledby
may refer to elements otherwise hidden from the accessibility tree
- Recall that
treeitem
rolebutton
rolecheckbox
role
Question 1:
<div role="treeitem" aria-hidden>
Semantics
</div>
Answer
Answer: Semantics
Question 2:
<button hidden>
Sign up
</button>
Answer
Answer: No label
Question 3:
<span role="checkbox" aria-labelledby="label">
<span hidden id="label">
Styling
</span>
Answer
Answer: Styling
Question 4:
<span role="button">
<span class="icon icon-menu" role="img" aria-label="menu">
</span>
</span>
Answer
Answer: menu
- aria-live
- aria-atomic
- aria-relevant
- aria-busy
WebAIM checklist items:
Proposing CSS input modality article
For example
<!-- bad -->
<div class="toggle"
role="button"
aria-labelledby="muteLbl"
aria-pressed="false">
</div>
<!-- good -->
<div class="toggle pressed"
role="button"
aria-labelledby="muteLbl"
aria-pressed="true">
</div>
/* bad */
.toggle.pressed {
}
/* good */
.toggle[aria-pressed="true"] {
}
-
Use a meta viewport tag
<meta name="viewport" content="width=device-width, initial-scale=1">
-
Use relative size
- width: 50% -
relative to the containing block
- font-size: 1.2em -
relative to the font-size of the parent
- font-size: 2rem -
relative to the font-size of the root
- width: 50% -
-
Use appropriate touch targets
48dp
minimum touch target size32dp
margin around touch target
WebAIM checklist items:
Udacity course on Responsive Web Design Fundamentals
Responsive web design basics on Web Fundamentals
Material Design Accessibility recommendations for touch targets
Author's Note: On older browsers (particularly Mobile Safari) developers would add user-scaleable=no
because it would disable the 350ms click delay in that browser. As of Safari 9.1 this is no longer the case, and using width=device-width
in your viewport will handle removing that click delay
WebAIM checklist items:
- 1.4.3: http://webaim.org/standards/wcag/checklist#sc1.4.3
- 1.4.6: http://webaim.org/standards/wcag/checklist#sc1.4.6
WebAIM checklist items:
For more information on color blindness, check out the Colour Blind Awareness site.
You can follow this link to get the Chrome High Contrast extension. Try it out on one of your sites to verify that everything works well for low vision users.
How frequently
is this piece of UI used?
How badly does this accessibility issue affect
your users?
How expensive
is it going to be to fix?
good a11y = good UX