How to be an a11y - Creating Accessible React Apps
By Neha Nivedita
What is accessibility
- Everyone can access services or products equally
- Usability regardless of disability
- Commonly abbreviated as "a11y" or "AX"
ARIA: accessible rich internet applications
ARIA is a set of special accessibility attributes which can be added to any markup, but is especially suited to HTML.
<button aria-label="Close Window">
X
</button>
<a href="/card-design-woes"
aria-describedby="desc-card-design-woes"
>
Card design woes
</a>
<span class="cta" aria-hidden="true">
I am hidden from screen readers
</span>
Why should you care?
- 15% of population has some form of disability - that's 1 billion people
- 8% of population has some form of colorblindness
- AX isn't a feature, its a necessity
- Ignoring AX is akin to discrimination
Sources of a11y issuesÂ
- Devs often write non-semantic HTML
- Screen readers cannot parse the content meaningfully
- Apps become inaccessible
<div
onClick={this.onClick}
className={looklikeAButton}
>
Click Me
</div>
Making React apps accessible
Low hanging fruit
- Supports aria natively
- Get low hanging fruit out of the way first
- Use alt attributes
- Use semantic elements
<img
src="woman.jpg"
alt="Woman carrying an umbrella"
/>
<button class="btn">
Hey, I'm actually a button!
</button>
Update page titles
Page title is the thing screen readers usually read out loud
componentDidMount() {
document.title = 'Page title';
}
import React from 'react';
import { Helmet } from 'react-helmet';
const PageMeta = (props) => (
<Helmet>
<title>Eric's Website: {props.pageTitle}</title>
<meta
name="og_title"
property="og:title"
content={props.pageTitle}
/>
</Helmet>
);
Heading semantics
Use heading tags <h1>, <h2>, ... etc the way they are intended to, not just to make the text big.
<h1>Page Title</h1>
<h2>Subtitle</h2>
<h3>Sub-subtitle</h3>
...
Unique Ids
Useful for setting focus and label/input association
const FirstName = () => (
<div>
<label htmlFor="first-name">First name:</label>
<input id="first-name" />
</div>
);
Don't rely on placeholder's as a label
Announce changes
-
When something changes, users to be aware of it
-
Use aria-live attribute
const HomePage = (props) => (
<div
aria-live="polite"
aria-atomic="true"
>
{props.children}
</div>
);
See react-aria-live: https://github.com/AlmeroSteyn/react-aria-live
Manage focus
-
Ensure when routes update, window focus is set in an appropriate locaiton
-
When react router changes, the change is silent
-
Use refs to set focus and set tabIndex="-1"
class Page extends React.Component {
focalPoint = React.createRef();
componentDidMount() {
this.focalPoint.current.focus();
}
render() {
return (
<section ref={this.focalPoint} tabIndex="-1">
{/* ... */}
</section>
)
}
}
How to be an a11y - Creating Accessible React Apps
By Eric Masiello
How to be an a11y - Creating Accessible React Apps
- 266