Categories
JavaScript React

Creating Accessible React Apps — Focus and Semantics

Spread the love

React is a library for creating front end views. It has a big ecosystem of libraries that work with it. Also, we can use it to enhance existing apps.

In this article, we’ll look at how to create accessible React apps.

Why Accessibility?

We should create accessible apps so that they can be used by everyone.

Standards and Guidelines

The Web Content Accessibility Guidelines provide guidelines for creating accessible web sites.

Also, we have the Web Accessibility Initiative — Accessible Rich Internet Applications document contains guidelines for building fully accessible JavaScript widgets.

aria-* HTML attributes are fully supported in JSX. These attributes are kept as kebab-case as they’re in HTML.

Semantic HTML

HTML tags are named for their meanings. This means that they make sense for screen readers and other accessibility programs that parse web content.

This means that instead of using div to group elements, we should use Fragments instead so that our app doesn’t have extra div elements getting in the way of screen readers.

For example, we can add fragments to a component as follows:

function ListItem({ item }) {  
  return (  
    <Fragment>  
      <dt>{item.term}</dt>  
      <dd>{item.meaning}</dd>  
    </Fragment>  
  );  
}

class App extends React.Component {  
  constructor(props) {  
    super(props);  
    this.state = {  
      items: [  
        { term: "coffee", meaning: "black drink" },  
        { term: "milk", meaning: "white drink" }  
      ]  
    };  
  } 

  render() {  
    return (  
      <dl>  
        {this.state.items.map(item => (  
          <ListItem item={item} key={item.id} />  
        ))}  
      </dl>  
    );  
  }  
}

Then we get the following HTML rendered:

<dl>  
  <dt>coffee</dt>  
  <dd>black drink</dd>  
  <dt>milk</dt>  
  <dd>white drink</dd>  
</dl>

As we can see, fragments do not produce any extra HTML but let us group elements together.

A shorthand or fragments are <> and </> . Therefore, we can rewrite the code above as follows:

function ListItem({ item }) {  
  return (  
    <>  
      <dt>{item.term}</dt>  
      <dd>{item.meaning}</dd>  
    </>  
  );  
}

We keep the rest of the code the same.

Then we get the same HTML rendered.

Accessible Forms

We should label forms to provide accessibility for all users.

To do this, we add a for attribute to label elements. In React, the for element represented by the htmlFor prop.

This applies to all form controls.

For example, we can do the following to add a htmlFor prop:

class App extends React.Component {  
  constructor(props) {  
    super(props);  
    this.state = { name: "" };  
  } 

  render() {  
    return (  
      <>  
        <label htmlFor="name">Name:</label>  
        <input type="text" name="name" value={this.state.name} />  
      </>  
    );  
  }  
}

In the code above, we have:

htmlFor="name"

to relate the label to the form field. The htmlFor value should be the same as the name value of the form control element.

The full accessibility guidelines are at:

Notifying the user of errors

Errors need to understood by users. The following guides tells us how to expose error text to screen readers:

Focus Control

We should only change or remove outlines by using CSS so that users can get the focused element even without seeing the outline.

Ways to Skip to Desired Content

Also, we should provide ways for users to skip to what they want to see or use.

We can implement that with internal page anchors and some styling.

We can also put important content in elements like main and aside so that they can be differentiated from other content.

Programmatically Managing Focus

In React, we can access DOM elements by using refs. This means that we can control when an element is in focus by calling DOM methods to focus an element.

For example, if we want to focus an element when the component is mounted in the DOM tree, we can call focus as follows:

class App extends React.Component {  
  constructor(props) {  
    super(props);  
    this.textInput = React.createRef();  
  } 

  componentDidMount() {  
    this.textInput.current.focus();  
  } 

  render() {  
    return <input type="text" ref={this.textInput} />;  
  }  
}

In the code above, we created a ref to access the DOM element by writing:

this.textInput = React.createRef();

In the input element, we have:

ref={this.textInput}

to associate the input element with the ref we created.

Then in the componentDidMount hook, we have:

this.textInput.current.focus();

to focus the input when the component mounts. this.textInput.current returns the input element, so that we can call the native focus method on it.

Conclusion

When creating React apps, we should have accessibility in mind.

This means that we should use semantic HTML tags so that all users can understand what a page has.

Also, we should provide ways for users to skip to the content that they want to see.

Finally, we can focus elements programmatically so that users can use inputs right away when focus is lost by regaining focus.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *