|
| 1 | +--- |
| 2 | +id: accessibility |
| 3 | +title: Accessibility |
| 4 | +permalink: docs/accessibility.html |
| 5 | +redirect_from: |
| 6 | + - "docs/index.html" |
| 7 | +--- |
| 8 | + |
| 9 | +## Why Accessibility? |
| 10 | + |
| 11 | +Web accessibility (also referred to as [**a11y**](https://en.wiktionary.org/wiki/a11y)) is the design and creation of websites that can be used by everyone. Accessibility support is necessary to allow assistive technology to interpret web pages. |
| 12 | + |
| 13 | +React fully supports building accessible websites, often by using standard HTML techniques. |
| 14 | + |
| 15 | +## Standards and Guidelines |
| 16 | + |
| 17 | +### WCAG |
| 18 | + |
| 19 | +The [Web Content Accessibility Guidelines](https://www.w3.org/WAI/intro/wcag) provides guidelines for creating accessible web sites. |
| 20 | + |
| 21 | +The following WCAG checklists provide an overview: |
| 22 | + |
| 23 | +- [WCAG checklist from Wuhcag](https://www.wuhcag.com/wcag-checklist/) |
| 24 | +- [WCAG checklist from WebAIM](http://webaim.org/standards/wcag/checklist) |
| 25 | +- [Checklist from The A11Y Project](http://a11yproject.com/checklist.html) |
| 26 | + |
| 27 | +### WAI-ARIA |
| 28 | + |
| 29 | +The [Web Accessibility Initiative - Accessible Rich Internet Applications](https://www.w3.org/WAI/intro/aria) document contains techniques for building fully accessible JavaScript widgets. |
| 30 | + |
| 31 | +Note that all `aria-*` HTML attributes are fully supported in JSX. Whereas most DOM properties and attributes in React are camelCased, these attributes should be lowercased: |
| 32 | + |
| 33 | +```javascript{3,4} |
| 34 | +<input |
| 35 | + type="text" |
| 36 | + aria-label={labelText} |
| 37 | + aria-required="true" |
| 38 | + onChange={onchangeHandler} |
| 39 | + value={inputValue} |
| 40 | + name="name" |
| 41 | +/> |
| 42 | +``` |
| 43 | + |
| 44 | +## Accessible Forms |
| 45 | + |
| 46 | +### Labeling |
| 47 | +Every HTML form control, such as `<input>` and `<textarea>`, needs to be labeled accessibly. We need to provide descriptive labels that are also exposed to screen readers. |
| 48 | + |
| 49 | +The following resources show us how to do this: |
| 50 | + |
| 51 | +- [The W3C shows us how to label elements](https://www.w3.org/WAI/tutorials/forms/labels/) |
| 52 | +- [WebAIM shows us how to label elements](http://webaim.org/techniques/forms/controls) |
| 53 | +- [The Paciello Group explains accessible names](https://www.paciellogroup.com/blog/2017/04/what-is-an-accessible-name/) |
| 54 | + |
| 55 | +Although these standard HTML practices can be directly used in React, note that the `for` attribute is written as `htmlFor` in JSX: |
| 56 | + |
| 57 | +```javascript{1} |
| 58 | +<label htmlFor="namedInput">Name:</label> |
| 59 | +<input id="namedInput" type="text" name="name"/> |
| 60 | +``` |
| 61 | + |
| 62 | +### Notifying the user of errors |
| 63 | + |
| 64 | +Error situations need to be understood by all users. The following link show us how to expose error texts to screen readers as well: |
| 65 | + |
| 66 | +- [The W3C demonstrates user notifications](https://www.w3.org/WAI/tutorials/forms/notifications/) |
| 67 | +- [WebAIM looks at form validation](http://webaim.org/techniques/formvalidation/) |
| 68 | + |
| 69 | +## Focus Control |
| 70 | + |
| 71 | +Ensure that your web application can be fully operated with the keyboard only: |
| 72 | + |
| 73 | +- [WebAIM talks about keyboard accessibility](http://webaim.org/techniques/keyboard/) |
| 74 | + |
| 75 | +### Keyboard focus and focus outline |
| 76 | + |
| 77 | +Keyboard focus refers to the current element in the DOM that is selected to accept input from the keyboard. We see it everywhere as a focus outline similar to the that shown in the following image: |
| 78 | + |
| 79 | +<img src="/react/img/docs/keyboard-focus.png" alt="Blue keyboard focus outline around a selected link." /> |
| 80 | + |
| 81 | +Only ever use CSS that removes this outline, for example by setting `outline: 0`, if you are replacing it with another focus outline implementation. |
| 82 | + |
| 83 | +### Mechanisms to skip to desired content |
| 84 | + |
| 85 | +Provide a mechanism to allow users to skip past navigation sections in your application as this assists and speeds up keyboard navigation. |
| 86 | + |
| 87 | +Skiplinks or Skip Navigation Links are hidden navigation links that only become visible when keyboard users interact with the page. They are very easy to implement with |
| 88 | +internal page anchors and some styling: |
| 89 | + |
| 90 | +- [WebAIM - Skip Navigation Links](http://webaim.org/techniques/skipnav/) |
| 91 | + |
| 92 | +Also use landmark elements and roles, such as `<main>` and `<aside>`, to demarcate page regions as assistive technology allow the user to quickly navigate to these sections. |
| 93 | + |
| 94 | +Read more about the use of these elements to enhance accessibility here: |
| 95 | + |
| 96 | +- [Deque University - HTML 5 and ARIA Landmarks](https://dequeuniversity.com/assets/html/jquery-summit/html5/slides/landmarks.html) |
| 97 | + |
| 98 | +### Programmatically managing focus |
| 99 | + |
| 100 | +Our React applications continuously modify the HTML DOM during runtime, sometimes leading to keyboard focus being lost or set to an unexpected element. In order to repair this, |
| 101 | +we need to programmatically nudge the keyboard focus in the right direction. For example, by resetting keyboard focus to a button that opened a modal window after that modal window is closed. |
| 102 | + |
| 103 | +The Mozilla Developer Network takes a look at this and describes how we can build [keyboard-navigable JavaScript widgets](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Keyboard-navigable_JavaScript_widgets). |
| 104 | + |
| 105 | +To set focus in React, we can use [Refs to Components](refs-and-the-dom.html). |
| 106 | + |
| 107 | +Using this, we first create a ref to an element in the JSX of a component class: |
| 108 | + |
| 109 | +```javascript{2-3,7} |
| 110 | +render() { |
| 111 | + // Use the `ref` callback to store a reference to the text input DOM |
| 112 | + // element in an instance field (for example, this.textInput). |
| 113 | + return ( |
| 114 | + <input |
| 115 | + type="text" |
| 116 | + ref={(input) => { this.textInput = input; }} /> |
| 117 | + ); |
| 118 | +} |
| 119 | +``` |
| 120 | + |
| 121 | +Then we can focus it elsewhere in our component when needed: |
| 122 | + |
| 123 | + ```javascript |
| 124 | + focus() { |
| 125 | + // Explicitly focus the text input using the raw DOM API |
| 126 | + this.textInput.focus(); |
| 127 | + } |
| 128 | + ``` |
| 129 | + |
| 130 | +A great focus management example is the [react-aria-modal](https://github.com/davidtheclark/react-aria-modal). This is a relatively rare example of a fully accessible modal window. Not only does it set initial focus on |
| 131 | +the cancel button (preventing the keyboard user from accidentally activating the success action) and trap keyboard focus inside the modal, it also resets focus back to the element that |
| 132 | +initially triggered the modal. |
| 133 | + |
| 134 | +>Note: |
| 135 | +
|
| 136 | +>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 |
| 137 | +>users want to use applications. |
| 138 | +
|
| 139 | +## More Complex Widgets |
| 140 | + |
| 141 | +A more complex user experience should not mean a less accessible one. Whereas accessibility is most easily achieved by coding as close to HTML as possible, |
| 142 | +even the most complex widget can be coded accessibly. |
| 143 | + |
| 144 | +Here we require knowledge of [ARIA Roles](https://www.w3.org/TR/wai-aria/roles) as well as [ARIA States and Properties](https://www.w3.org/TR/wai-aria/states_and_properties). |
| 145 | +These are toolboxes filled with HTML attributes that are fully supported in JSX and enable us to construct fully accessible, highly functional React components. |
| 146 | + |
| 147 | +Each type of widget has a specific design pattern and is expected to function in a certain way by users and user agents alike: |
| 148 | + |
| 149 | +- [WAI-ARIA Authoring Practices - Design Patterns and Widgets](https://www.w3.org/TR/wai-aria-practices/#aria_ex) |
| 150 | +- [Heydon Pickering - ARIA Examples](http://heydonworks.com/practical_aria_examples/) |
| 151 | +- [Inclusive Components](https://inclusive-components.design/) |
| 152 | + |
| 153 | +## Other Points for Consideration |
| 154 | + |
| 155 | +### Setting the language |
| 156 | + |
| 157 | +Indicate the human language of page texts as screen reader software uses this to select the correct voice settings: |
| 158 | + |
| 159 | +- [WebAIM - Document Language](http://webaim.org/techniques/screenreader/#language) |
| 160 | + |
| 161 | +### Setting the document title |
| 162 | + |
| 163 | +Set the document `<title>` to correctly describe the current page content as this ensures that the user remains aware of the current page context: |
| 164 | + |
| 165 | +- [WCAG - Understanding the Document Title Requirement](https://www.w3.org/TR/UNDERSTANDING-WCAG20/navigation-mechanisms-title.html) |
| 166 | + |
| 167 | +We can set this in React using the [React Document Title Component](https://github.com/gaearon/react-document-title). |
| 168 | + |
| 169 | +### Color contrast |
| 170 | + |
| 171 | +Ensure that all readable text on your website has sufficient color contrast to remain maximally readable by users with low vision: |
| 172 | + |
| 173 | +- [WCAG - Understanding the Color Contrast Requirement](https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html) |
| 174 | +- [Everything About Color Contrast And Why You Should Rethink It](https://www.smashingmagazine.com/2014/10/color-contrast-tips-and-tools-for-accessibility/) |
| 175 | +- [A11yProject - What is Color Contrast](http://a11yproject.com/posts/what-is-color-contrast/) |
| 176 | + |
| 177 | +It can be tedious to manually calculate the proper color combinations for all cases in your website so instead, you can [calculate an entire accessible color palette with Colorable](http://jxnblk.com/colorable/). |
| 178 | + |
| 179 | +Both the aXe and WAVE tools mentioned below also include color contrast tests and will report on contrast errors. |
| 180 | + |
| 181 | +If you want to extend your contrast testing abilities you can use these tools: |
| 182 | + |
| 183 | +- [WebAIM - Color Contrast Checker](http://webaim.org/resources/contrastchecker/) |
| 184 | +- [The Paciello Group - Color Contrast Analyzer](https://www.paciellogroup.com/resources/contrastanalyser/) |
| 185 | + |
| 186 | +## Development and Testing Tools |
| 187 | + |
| 188 | +There are a number of tools we can use to assist in the creation of accessible web applications. |
| 189 | + |
| 190 | +### The keyboard |
| 191 | + |
| 192 | +By far the easiest and also one of the most important checks is to test if your entire website can be reached and used with the keyboard alone. Do this by: |
| 193 | + |
| 194 | +1. Plugging out your mouse. |
| 195 | +1. Using `Tab` and `Shift+Tab` to browse. |
| 196 | +1. Using `Enter` to activate elements. |
| 197 | +1. Where required, using your keyboard arrow keys to interact with some elements, such as menus and dropdowns. |
| 198 | + |
| 199 | +### Development assistance |
| 200 | + |
| 201 | +We can check some accessibility features directly in our JSX code. Often intellisense checks are already provided in JSX aware IDE's for the ARIA roles, states and properties. We also |
| 202 | +have access to the following tool: |
| 203 | + |
| 204 | +#### eslint-plugin-jsx-a11y |
| 205 | + |
| 206 | +The [eslint-plugin-jsx-a11y](https://github.com/evcohen/eslint-plugin-jsx-a11y) plugin for ESLint provides AST linting feedback regarding accessibility issues in your JSX. Many |
| 207 | +IDE's allow you to integrate these findings directly into code analysis and source code windows. |
| 208 | + |
| 209 | +[Create React App](https://github.com/facebookincubator/create-react-app) has this plugin with a subset of rules activated. If you want to enable even more accessibility rules, |
| 210 | +you can create an `.eslintrc` file in the root of your project with this content: |
| 211 | + |
| 212 | + ```json |
| 213 | + { |
| 214 | + "extends": ["react-app", "plugin:jsx-a11y/recommended"], |
| 215 | + "plugins": ["jsx-a11y"] |
| 216 | + } |
| 217 | + ``` |
| 218 | + |
| 219 | +### Testing accessibility in the browser |
| 220 | + |
| 221 | +A number of tools exist that can run accessibility audits on web pages in your browser. Please use them in combination with other accessibility checks mentioned here as they can only |
| 222 | +test the technical accessibility of your HTML. |
| 223 | + |
| 224 | +#### aXe, aXe-core and react-axe |
| 225 | + |
| 226 | +Deque Systems offers [aXe-core](https://www.deque.com/products/axe-core/) for automated and end-to-end accessibility tests of your applications. This module includes integrations for Selenium. |
| 227 | + |
| 228 | +[The Accessibility Engine](https://www.deque.com/products/axe/) or aXe, is an accessibility inspector browser extension built on `aXe-core`. |
| 229 | + |
| 230 | +You can also use the [react-axe](https://github.com/dylanb/react-axe) module to report these accessibility findings directly to the console while developing and debugging. |
| 231 | + |
| 232 | +#### WebAIM WAVE |
| 233 | + |
| 234 | +The [Web Accessibility Evaluation Tool](http://wave.webaim.org/extension/) is another accessibility browser extension. |
| 235 | + |
| 236 | +#### Accessibility inspectors and the Accessibility Tree |
| 237 | + |
| 238 | +[The Accessibility Tree](https://www.paciellogroup.com/blog/2015/01/the-browser-accessibility-tree/) is a subset of the DOM tree that contains accessible objects for every DOM element that should be exposed |
| 239 | +to assistive technology, such as screen readers. |
| 240 | + |
| 241 | +In some browsers we can easily view the accessibility information for each element in the accessibility tree: |
| 242 | + |
| 243 | +- [Activate the Accessibility Inspector in Chrome](https://gist.github.com/marcysutton/0a42f815878c159517a55e6652e3b23a) |
| 244 | +- [Using the Accessibility Inspector in OS X Safari](https://developer.apple.com/library/content/documentation/Accessibility/Conceptual/AccessibilityMacOSX/OSXAXTestingApps.html) |
| 245 | + |
| 246 | +### Screen readers |
| 247 | + |
| 248 | +Testing with a screen reader should form part of your accessibility tests. |
| 249 | + |
| 250 | +Please note that browser / screen reader combinations matter. It is recommended that you test your application in the browser best suited to your screen reader of choice. |
| 251 | + |
| 252 | +#### NVDA in FireFox |
| 253 | + |
| 254 | +[NonVisual Desktop Access](https://www.nvaccess.org/) or NVDA is an open source Windows screen reader that is widely used. |
| 255 | + |
| 256 | +Refer to the following guides on how to best use NVDA: |
| 257 | + |
| 258 | +- [WebAIM - Using NVDA to Evaluate Web Accessibility](http://webaim.org/articles/nvda/) |
| 259 | +- [Deque - NVDA Keyboard Shortcuts](https://dequeuniversity.com/screenreaders/nvda-keyboard-shortcuts) |
| 260 | + |
| 261 | +#### VoiceOver in Safari |
| 262 | + |
| 263 | +VoiceOver is an integrated screen reader on Apple devices. |
| 264 | + |
| 265 | +Refer to the following guides on how activate and use VoiceOver: |
| 266 | + |
| 267 | +- [WebAIM - Using VoiceOver to Evaluate Web Accessibility](http://webaim.org/articles/voiceover/) |
| 268 | +- [Deque - VoiceOver for OSX Keyboard Shortcuts](https://dequeuniversity.com/screenreaders/voiceover-keyboard-shortcuts) |
| 269 | +- [Deque - VoiceOver for iOS Shortcuts](https://dequeuniversity.com/screenreaders/voiceover-ios-shortcuts) |
| 270 | + |
| 271 | +#### JAWS in Internet Explorer |
| 272 | + |
| 273 | +[Job Access With Speech](http://www.freedomscientific.com/Products/Blindness/JAWS) or JAWS, is a prolifically used screen reader on Windows. |
| 274 | + |
| 275 | +Refer to the following guides on how to best use JAWS: |
| 276 | + |
| 277 | +- [WebAIM - Using JAWS to Evaluate Web Accessibility](http://webaim.org/articles/jaws/) |
| 278 | +- [Deque - JAWS Keyboard Shortcuts](https://dequeuniversity.com/screenreaders/jaws-keyboard-shortcuts) |
0 commit comments