Getting Started with Web Accessibility in React

[I have re-published this on my personal blog]

When designing shiny new web applications using React, it’s easy to forget about the accessibility of what you are developing, or even failing to consider what native features React provides to help make the web more accessible. I am going to cover some basic features that React enables and/or supports, as well as some basic implementations.

In the React documentation, accessibility is covered in some detail, as well as outlining some key resources that developers should look into when focusing on the accessibility of React web applications.

React fully supports building accessible websites, often by using standard HTML techniques.

When considering web accessibility, you need to understand the standard HTML features which help assistive technologies to interpret web pages. Many of the features react supports are standard HTML accessibility practice. If you want to learn a bit more about this, I have written another blog post called Getting Started with Web Accessibility, which covers these topics in more detail.

How does React work?

An HTML document will be represented by a Document Object Model (DOM). The DOM represents the HTML document as a collection of Nodes and Objects, much like a tree. It is a programming interface allowing for programs to modify the document’s structure or content.

When building ‘traditional’ web applications, you will be playing around with the DOM a lot. You may use jQuery to ‘grab’ or ‘insert’ elements from the DOM, such as in the example below:

let container = document.getElementById('container')
let image = document.createElement('img')
image.src = ''

The DOM is essentially just an object-oriented representation of all the items in a web page, encapsulating all of the methods and properties available for each of them in an object. The document is itself an object.

The DOM was designed to be independent of any particular programming language, making the structural representation of the document available from a single, consistent API.

Updating the DOM directly can be quite expensive. React provides an alternative way of performing DOM updates, and this is through building a ‘Virtual DOM’. For every DOM object, there will be a corresponding object in the Virtual DOM.

So, whilst the Virtual DOM is essentially just a clone of the DOM, it doesn’t have the power to modify what a user sees. This actually makes the whole process faster, as changes to the virtual DOM can be ‘batched’, and diff operations can take place at the end of event loops.

When you render a JSX element, every Virtual DOM node will be updated, and then React does a ‘diff operation’ between the Virtual DOM prior to the update, and the Virtual DOM now, after the update, and can understand which objects have been changed.


Due to this, only the nodes that have changed are modified in the DOM. It is also important to note that the Virtual DOM does have a different API to the ‘real’ DOM, as nodes in React’s virtual DOM are abstracted as Components. React’s virtual DOM also contains application-specific and defined components, whereas the real DOM will only contain ‘built-in’ elements such as <p> .

It is important to understand how updates in React are made, and how web pages are constructed, to fully understand why web accessibility features may exist, or be slightly modified.

Getting Started with Accessibility in React

There are a few basic steps you can take to ensure that your web application is as accessible as possible, as quickly as possible. I will provide some further resources if you want to take this one step further at the end of this post.

Keyboard Focus

Keyboard focus is something that is key to note when implementing accessible sites. Users who cannot use other input mechanisms will struggle to interact with your site if you don’t ensure that keyboard focus is properly managed.

The keyboard focus is the current element in the DOM “which is currently receiving keyboard input”. A standard example of a focused element is the blue outline we see around buttons regularly. It is standard practice never to remove this default outline, unless you are replacing it with an alternative implementation.

Image for post
Image for post
The ‘google search’ button being keyboard focused.

Due to the regular DOM changes made in React applications, this can lead to problems with keyboard focus. This can include keyboard focus being lost, unexpectedly changed to a different element, leading to frustration of the user, as well as users relying on assistive technologies being disoriented. The React team, therefore, provides guidance on how to programatically control keyboard focus.

React provides Refs in order to modify child components or elements outside of the typical update- and data-flow. These can be used to manage keyboard focus. The ref attribute can be placed on any React component, with a function value. This function will be “executed as soon as the component is mounted or unmounted”. The first parameter of the function will be a reference to the element or the component the ref is on (

Below I have slightly modified an example of the usage of Refs from here to use React component syntax. This example outlines how the Ref attribute means the keyboard focus is maintained on the text input field after the button is clicked.

While this is a very important accessibility feature, it is also a technique that should be used judiciously. Use it to repair the keyboard focus flow when it is disturbed, not to try and anticipate how users want to use applications. — React Documentation


Accessible Rich Internet Applications (ARIA) is a set of attributes that define ways to make Web content and Web applications more accessible for users with disabilities. There is a large set of built-in HTML attributes to define ‘roles’ for an element, to provide more information to users using assistive technology, or providing nice ways to split a page up.

ARIA HTML attributes are fully supported in JSX, and therefore can be used as attributes for elements and components in React. Unlike most attributes, ARIA attributes should be lowercased when declared, but the fundamental usage remains the same as in traditional web development.

You can also use ARIA roles and landmarks to provide programatic access to sections or ‘landmarks’ of a webpage. This will further facilitate keyboard accessibility, as well as allow for skip links to be used. Skip links are hidden links that are only exposed to keyboard users, allowing them to navigate to or past a certain part of your page.


Fragments are a pattern used in React which allow a component to return multiple elements, without an encompassing <div> component. Using <div> elements in certain contexts in React may break HTML semantics, leading to difficult-to-understand page structures, or invalid HTML.

Lets say you are building a <ul> (unordered list) where, for every bullet point in the list, you want to return multiple components. You may try to do this:

In this example,<ListItem> would need to return 1 or more <li> elements to be valid. If a parent <div> element was used inside the render function of ListItem then the generated HTML of List would be invalid:

A Fragment would, instead, hold the <li> elements , just like a <div> but without adding another element to the DOM. The example would end up looking like this:

And the output would be valid HTML:

Fragments help keep the HTML valid and understandable, especially to users without access to the visuals of the page, and who may be reliant on screen reader technologies for example.

Setting the Title

Due to the fact that React applications are Single Page Web Applications, the same title value will be used throughout the user’s journey in the application, which isn’t necessarily ideal.

Typically, you can set the title element value in the public/index.html file. This would never change unless you programatically update it throughout the users browsing experience. A popular solution is using react-document-title , an NPM package providing a declarative way to set the title value.

The package allows you to define app- and page-specific titles, which gives the user a better experience, without inserting any DOM element.

As is noted on the w3c site ‘Easy Checks’ article, the page title is shown in the tab bar on most browsers, shown in search engine results, and read by screen readers. You should check that your title is correctly describing the content of the page, and that it is different from other pages on the website as to distinguish the page from other web pages.

Good page titles are particularly important for orientation — to help people know where they are and move between pages open in their browser. The first thing screen readers say when the user goes to a different web page is the page title. — w3c

Usage of this feature is quite simple. Below is the example from the react-document-title documentation (assuming you are using React router).

Development and Testing Tools

The React ecosystem is large and constantly growing, with a lot of tools out there which can help developers to make more accessible web applications. I will go over a few of them here- but I am definitely open to other suggestions if you have any!


This linter plugin enables accessibility checking of your code as you develop your application. Assuming you are using an editor linting plugin, you can ensure you are meeting some accessibility standards from the very beginning, with real-time understanding.

There are 33 currently-testable rules enabled in this plugin, including alt-text and label-has-for. This by no means ensures that you will be fully accessible, but is an incredible first step in the right direction.

Create React app has this plugin installed, with a subset of the rules activated. You can extend this by creating an .eslintrc file, to enable more rules.


This is a similar tool to the eslint plugin, but this is a runtime-analysis tool which is a package to include in your application. You need to require the module, and use it in your main application file. You will then get warnings in your console when you render your application.

Image for post
Image for post
Example of react-a11y warnings. Source:

You can also use this tool in your testing environment, and pass in more plugins if you want to test for further rules. The default of this tool is to throw warnings when something is wrong, however you can set the severity if you would rather errors would be thrown for example.

An alternative (or friend) of this tool may be react-axe, which tests the accessibility of the rendered DOM.


This modal library is compliant with web accessibility standards, and is recommended by the React team. It manages keyboard focus, key mapping, and ARIA roles, ensuring that your modal is accessible to screen readers.

The modal component will wrap your component so that it is easy to use and customisable, as well as enforcing accessibility rules. Modals are some of the least accessible features of sites, and so this tool is hugely useful.

Web AIM Colour Contrast Checker

In the Web Content Accessibility Guidelines, it is recommended that, for Level AA, that you have a colour contrast ratio of 4.5:1 for normal text. Level AAA requires a contrast ratio of 7:1 for normal text.

This tool will analyse the two colours you have picked, and provide the colour contrast ratio. You can find out, when developing a colour scheme, whether it will violate any accessibility guidelines.

WAVE Browser Extensions

WAVE is a free community service developed by WebAIM. They have developed browser extensions for Chrome and Firefox, which operate entirely within the browser. This means that no data is sent to the WAVE server, leading to secure accessibility reporting.

This can be used for almost any web page, including locally-displayed styles and dynamically-generated content. It is free to install and use.


Lighthouse was developed by Google as an automated tool for auditing the performance and accessibility of web pages. It can be used within Chrome DevTools, from the command line, or as a Node module. You just give it a URL, and it will generate a report.

Each audit it generates will also be accompanies by a document explaining the importance of the audit, along with ways to fix the page. You can view your reports online, as well as share them as JSON or GitHub Gists.

Written by

computer science student at ucl, feminist, cheese fan, vue / react, looking forward to the future 🌏

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store