Achieving Accessibility in React Applications

February 14, 2019 0 Comments

Achieving Accessibility in React Applications

 

 

Photo by Paul Green on Unsplash

Web Accessibility is the design of pages, tools and technologies on the web that can be used by everyone. Everyone here includes people with auditory, cognitive, neurological, physical, speech and visual disabilities. Accessibility support is necessary to allow assistive technology to interpret web pages and applications.

A11y is a numero-nym that stands for accessibility as “a” followed by 11 more letters, followed by “y”. Web development with accessibility in mind, ensures total inclusion of the entire population that use the web.

Web Accessibility as a feature has been seen as a very wrong way of design thinking because by default it excludes a large number of web users. People who cannot see or for some reason cannot use a trackpad or a mouse pointer for instance should have as much rights and access as people who can. Inclusive design starts by thinking about every web user equally, this would easily make you see web accessibility as a must and not a feature. Web accessibility also benefits people without disabilities, these people may include:

  • people using mobile phones, smart watches, smart TVs, and other devices with small screens, different input modes, etc.
  • older people with changing abilities due to ageing.
  • people with “temporary disabilities” such as a broken arm or lost glasses
  • people with “situational limitations” such as in bright sunlight or in an environment where they cannot listen to audio
  • people using a slow Internet connection, or who have limited or expensive bandwidth

These are guidelines that govern how accessibility is achieved while building for and using the web. These ensure that there is support for screen readers, keyboard usability and captions for photos. Some of them are:

WCAG: The Web Content Accessibility Guidelines provides guidelines for creating accessible web sites. WCAG is developed through the W3C process in cooperation with individuals and organisations around the world, with a goal of providing a single shared standard for web content accessibility that meets the needs of individuals, organisations, and governments internationally.

WAI-ARIA: The Web Accessibility Initiative — Accessible Rich Internet Applications document contains techniques for building fully accessible JavaScript widgets. It especially helps with dynamic content and advanced user interface controls developed with Ajax, HTML, JavaScript, and related technologies like React.

I would argue that the most dominant issue we have when trying to build accessible apps is caused by developers writing non-semantic code. Using JSX in inefficient ways that when compiled, the code would not be exactly semantic HTML. And we know that whenever there is non semantic HTML, assistive technologies like screen readers find it difficult to parse the content as it was intended. This process ends up in making the apps non-accessible.

React fully supports building accessible websites, often by using standard HTML techniques. We are going to look a few ways to make your react applications more accessible.

Tip: Use Bit to build React apps faster with components. It helps your team share components and reuse them to quickly build new apps. It’s great for keeping a set of accessible components you can use. Give it a try.

Writing semantic HTML in your React components would require that you pay attention to casing of attributes. In react, most HTML attributes are written in camel case.

maxlength becomes maxLength
tabindex becomes tabIndex
contenteditable becomes contentEditable

However, all aria-* HTML attributes are fully supported in JSX these attributes should be hyphen-cased kebab-cased as they are in plain HTML:

  aria-label={labelText}
aria-required="true"

For reserved words, we have that some reserved words mean entirely different things in HTML and in javascript words like class and for are practical examples, so in React we change them like thus:

for becomes htmlFor
class becomes className

Setting the page title is another very powerful step to making your react application very accessible. It is actually crucial for screen readers, the page title is the first thing screen readers announce. It updates the content currently showing in the browser tab helping to announce exactly where the users (who might depend on screen readers) are in your application. It is also really great for search engine optimisation. It is done like this:

componentDidMount() {
  document.title = “this is the page title”;
}

There is also a plugin you can use instead, react-helmet where you essentially handle head tags per page/component. This can be done like this:

import React from "react";
import {Helmet} from "react-helmet";

class Application extends React.Component {
render () {
return (
<div className="application">
<Helmet>
<meta charSet="utf-8" />
<title>My Title</title>
<link rel="canonical" href="http://mysite.com/example"; />
</Helmet>
...
</div>
);
}
};

To ensure that every code block of yours is going to be accessible, write good HTML code. We all make the quick button mistake:

<div onClick={this.onClick}
  className=”button”>
   <span>Click on me</span>
</div>

This would render a button, but it is not an accessible HTML button, a screen reader would not be able to interpret this. A more accessible and semantic code that does the same thing is this:

<button onClick={this.onClick}>
  Click on me
</button>

This is very important for every non-text content. Text is the most optimal format for any content, so make sure to add text alternatives. For images, use the alt:

<img src="apple.png" alt=" A big picture of an Apple " />
All non-text content that is presented to the user has a text alternative that serves the equivalent purpose — Ire Aderinokun

For user interfaces, use labels:

<div role="navigation" aria-label="Primary">
<ul>
<li>...a list of links here ...</li>
</ul>
</div>
<div role="navigation" aria-label="Secondary">
<ul>
<li>...a list of links here ...</li>
</ul>
</div>

It is very important for assistive technologies like screen readers to use headers the way it was intended to be used and not in any other (confusing) form.

<h1> Main Heading </h1>
 <h2> Sub Heading </h2>
  <h3> Sub Sub Heading </h3>

Anytime you are tempted to just bring in a h1 tag because of font, kindly head to the css file and style the sub header font instead.

Make text content readable and understandable and make Web pages appear and operate in predictable ways — Ire Aderinokun

If your React application fetches any data from any external source like an API, it makes sense to put some kind of structure in place for people using assistive technologies to be aware of the fetching of data going on. We can achieve this with live announcements. Here is a sample live announcement component:

import React from "react";


class Announcements extends React.Component {
render () {
return (
<div aria-live="polite" aria-atomic="true"
className="visuallyhidden">
{this.props.message}
</div>
);
}
};
export default Announcements;
  • aria-live with the polite value indicates that the screen reader waits till everything else is read before reading the updated content.
  • aria-atomic attribute set to true tells the screen reader that all page content would be announced, not just the updated content.

After the announcement component has been created, to use the live announcement we:

  • first create a state property in a parent component
this.state = {
  message: null;
 };
  • then set message, optimally at the point where the API or fetch logic is:
this.setState({
  message: “this is currently happening mate!”
 });
  • finally, include the announcement component in the parent component like this:
<Announcements message={this.state.message} /> 

This would now set up live announcements properly for screen readers at specified points of your code where fetching of data occurs.

Fragments shipped with React 16.2.0, it allows you to group together a list of child elements without adding more nodes to the DOM. We know react component templates MUST always be wrapped with a HTML element for rendering to work correctly. This has made developers get really lazy and continuously wrap their code blocks with elements like divs (I used to always do this) We always end up with non-semantic HTML most times with the abuse of divs; remember how important semantic HTML is for accessibility.

Take a look at this sample template from my react.lazy tutorial

<div>
 {artists.map(artist =>(
  <div>
<li>1. Davido</li>
<li>2. Burna Boy</li>
</div>
  <div id=”card-body” key={artist.id}>
   <h1>MTV Base Headline Artists 2019</h1>
  </div>
 )}
<div/>

The highlighted div actually really looks harmless but might result to non-semantic and sometimes invalid HTML and even creation of extra nodes like this when compiled back to HTML:


<ul>
<div>
<li>1. Davido</li>
<li>2. Burna Boy</li>
</div>
</ul>

So using React Fragments is the right way to get around this problem I bet you must have had before. With fragments, we can now have the same template be like this:

<React.Fragment>
<li>1. Davido</li>
<li>2. Burna Boy</li>
</React.Fragment>

This results in really semantic HTML:

<ul>
<li>1. Davido</li>
<li>2. Burna Boy</li>
</ul>

For shortcut lovers like myself, there is an optional and simpler syntax for React fragments. It is the use of empty angle brackets:

<>
<li>1. Davido</li>
<li>2. Burna Boy</li>
</>

It is JSX syntax and it looks neater yes!

We can use ref functions to handle where we want the user to focus on in our application. As your react application is a single page application with routes, it is important that users with disabilities know when a new route renders in the DOM because screen readers are silent when routes change. A more modern type of ref was introduced with React 16.3.0 React.createRef(). Using the new ref, we can control the focus with the following steps:

  • Create a ref for the component you want to add focus on
  • Attach the created ref to the element to focus on
  • Set the focus with a lifecycle method.

As illustrated below:

class MyDivFocus extends Component {
 constructor (props) {
  super(props);
   this.myDiv = React.createRef();
 }
componentDidMount(){
 this.myDiv.current.focus();
}
render () {
 return (
  <div ref={this.myDiv} tabIndex= "-1">
   <h2> la la la</h2>
  </div>
  ); 
 }
}
  • You can install ESLint Plugin for Code Editors.
  • You can also install ESLint jsx-a11y plugin for your React projects to display accessibility rules you miss while building your application.
npm install eslint-plugin-jsx-a11y  -— save-dev
  • Update your eslint.rc file’s plugin and extends sections in your code editor. For plugin section:
“plugin”: [ 
  “jsx-a11y”
 ]

In the extends section:

“extends”: [
  “plugin: jsx-a11y/recommended”
]
  • Every quote in this article is from Ire’s blog, she is easily my favourite web developer.
  • I got some resources and insights from w3.org.
  • Some notes from a seminar from Scott Vinkle, Accessibility Advocate at Shopify.
  • The React Official Documentation.

By going through this article, you must have picked up various steps that would not only improve your efficiency writing React, but would also make you a global citizen, one who thinks equality and does not discriminate while building for the web. Now go out there and become an accessibility advocate, happy coding! Feel free to comment and ask anything 👐


Tag cloud