diff --git a/contributing/codebase-overview.html b/contributing/codebase-overview.html index 076d7c503e..93cff542ed 100644 --- a/contributing/codebase-overview.html +++ b/contributing/codebase-overview.html @@ -595,6 +595,11 @@ You can run npm run flow locally to check your code with Flow.

+
  • + Accessibility + +
  • + diff --git a/contributing/design-principles.html b/contributing/design-principles.html index 9df310005c..b8f33b430e 100644 --- a/contributing/design-principles.html +++ b/contributing/design-principles.html @@ -378,6 +378,11 @@ +
  • + Accessibility + +
  • + diff --git a/contributing/how-to-contribute.html b/contributing/how-to-contribute.html index 1108e0b30f..e308ede8a1 100644 --- a/contributing/how-to-contribute.html +++ b/contributing/how-to-contribute.html @@ -385,6 +385,11 @@ You can check the status of your code styling by simply running npm run li +
  • + Accessibility + +
  • + diff --git a/contributing/implementation-notes.html b/contributing/implementation-notes.html index f9655e0ae7..15f307d16a 100644 --- a/contributing/implementation-notes.html +++ b/contributing/implementation-notes.html @@ -1035,6 +1035,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/accessibility.html b/docs/accessibility.html new file mode 100644 index 0000000000..74e77c8006 --- /dev/null +++ b/docs/accessibility.html @@ -0,0 +1,679 @@ + + + + + + + + + Accessibility - React + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    + Edit on GitHub +

    + Accessibility +

    +
    + +

    Why Accessibility?

    + +

    Web accessibility (also referred to as 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.

    + +

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

    + +

    Standards and Guidelines

    + +

    WCAG

    + +

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

    + +

    The following WCAG checklists provide an overview:

    + + + +

    WAI-ARIA

    + +

    The Web Accessibility Initiative - Accessible Rich Internet Applications document contains techniques for building fully accessible JavaScript widgets.

    + +

    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:

    +
    <input
    +  type="text" 
    +  aria-label={labelText}
    +  aria-required="true"
    +  onChange={onchangeHandler}
    +  value={inputValue}
    +  name="name"
    +/>
    +
    +

    Accessible Forms

    + +

    Labeling

    + +

    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.

    + +

    The following resources show us how to do this:

    + + + +

    Although these standard HTML practices can be directly used in React, note that the for attribute is written as htmlFor in JSX:

    +
    <label htmlFor="namedInput">Name:</label>
    +<input id="namedInput" type="text" name="name"/>
    +
    +

    Notifying the user of errors

    + +

    Error situations need to be understood by all users. The following link show us how to expose error texts to screen readers as well:

    + + + +

    Focus Control

    + +

    Ensure that your web application can be fully operated with the keyboard only:

    + + + +

    Keyboard focus and focus outline

    + +

    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:

    + +

    Blue keyboard focus outline around a selected link.

    + +

    Only ever use CSS that removes this outline, for example by setting outline: 0, if you are replacing it with another focus outline implementation.

    + +

    Mechanisms to skip to desired content

    + +

    Provide a mechanism to allow users to skip past navigation sections in your application as this assists and speeds up keyboard navigation.

    + +

    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 +internal page anchors and some styling:

    + + + +

    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.

    + +

    Read more about the use of these elements to enhance accessibility here:

    + + + +

    Programmatically managing focus

    + +

    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, +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.

    + +

    The Mozilla Developer Network takes a look at this and describes how we can build keyboard-navigable JavaScript widgets.

    + +

    To set focus in React, we can use Refs to Components.

    + +

    Using this, we first create a ref to an element in the JSX of a component class:

    +
    render() {
    +  // Use the `ref` callback to store a reference to the text input DOM
    +  // element in an instance field (for example, this.textInput).
    +  return (
    +    <input
    +      type="text"
    +      ref={(input) => { this.textInput = input; }} />
    +  );
    +}
    +
    +

    Then we can focus it elsewhere in our component when needed:

    +
     focus() {
    +   // Explicitly focus the text input using the raw DOM API
    +   this.textInput.focus();
    + }
    +
    +

    A great focus management example is the react-aria-modal. This is a relatively rare example of a fully accessible modal window. Not only does it set initial focus on +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 +initially triggered the modal.

    + +
    +

    Note:

    + +

    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.

    +
    + +

    More Complex Widgets

    + +

    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, +even the most complex widget can be coded accessibly.

    + +

    Here we require knowledge of ARIA Roles as well as ARIA States and Properties. +These are toolboxes filled with HTML attributes that are fully supported in JSX and enable us to construct fully accessible, highly functional React components.

    + +

    Each type of widget has a specific design pattern and is expected to function in a certain way by users and user agents alike:

    + + + +

    Other Points for Consideration

    + +

    Setting the language

    + +

    Indicate the human language of page texts as screen reader software uses this to select the correct voice settings:

    + + + +

    Setting the document title

    + +

    Set the document <title> to correctly describe the current page content as this ensures that the user remains aware of the current page context:

    + + + +

    We can set this in React using the React Document Title Component.

    + +

    Color contrast

    + +

    Ensure that all readable text on your website has sufficient color contrast to remain maximally readable by users with low vision:

    + + + +

    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.

    + +

    Both the aXe and WAVE tools mentioned below also include color contrast tests and will report on contrast errors.

    + +

    If you want to extend your contrast testing abilities you can use these tools:

    + + + +

    Development and Testing Tools

    + +

    There are a number of tools we can use to assist in the creation of accessible web applications.

    + +

    The keyboard

    + +

    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:

    + +
      +
    1. Plugging out your mouse.
    2. +
    3. Using Tab and Shift+Tab to browse.
    4. +
    5. Using Enter to activate elements.
    6. +
    7. Where required, using your keyboard arrow keys to interact with some elements, such as menus and dropdowns.
    8. +
    + +

    Development assistance

    + +

    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 +have access to the following tool:

    + +

    eslint-plugin-jsx-a11y

    + +

    The eslint-plugin-jsx-a11y plugin for ESLint provides AST linting feedback regarding accessibility issues in your JSX. Many +IDE's allow you to integrate these findings directly into code analysis and source code windows.

    + +

    Create React App has this plugin with a subset of rules activated. If you want to enable even more accessibility rules, +you can create an .eslintrc file in the root of your project with this content:

    +
      {
    +    "extends": ["react-app", "plugin:jsx-a11y/recommended"],
    +    "plugins": ["jsx-a11y"]
    +  }
    +
    +

    Testing accessibility in the browser

    + +

    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 +test the technical accessibility of your HTML.

    + +

    aXe, aXe-core and react-axe

    + +

    Deque Systems offers aXe-core for automated and end-to-end accessibility tests of your applications. This module includes integrations for Selenium.

    + +

    The Accessibility Engine or aXe, is an accessibility inspector browser extension built on aXe-core.

    + +

    You can also use the react-axe module to report these accessibility findings directly to the console while developing and debugging.

    + +

    WebAIM WAVE

    + +

    The Web Accessibility Evaluation Tool is another accessibility browser extension.

    + +

    Accessibility inspectors and the Accessibility Tree

    + +

    The Accessibility Tree is a subset of the DOM tree that contains accessible objects for every DOM element that should be exposed +to assistive technology, such as screen readers.

    + +

    In some browsers we can easily view the accessibility information for each element in the accessibility tree:

    + + + +

    Screen readers

    + +

    Testing with a screen reader should form part of your accessibility tests.

    + +

    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.

    + +

    NVDA in FireFox

    + +

    NonVisual Desktop Access or NVDA is an open source Windows screen reader that is widely used.

    + +

    Refer to the following guides on how to best use NVDA:

    + + + +

    VoiceOver in Safari

    + +

    VoiceOver is an integrated screen reader on Apple devices.

    + +

    Refer to the following guides on how activate and use VoiceOver:

    + + + +

    JAWS in Internet Explorer

    + +

    Job Access With Speech or JAWS, is a prolifically used screen reader on Windows.

    + +

    Refer to the following guides on how to best use JAWS:

    + + + + +
    + + +
    +
    + + + +
    + + + + +
    + +
    + + + + diff --git a/docs/addons.html b/docs/addons.html index 15505d1caa..1632be8da8 100644 --- a/docs/addons.html +++ b/docs/addons.html @@ -271,6 +271,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/animation.html b/docs/animation.html index 2754c96a28..b87ef1b377 100644 --- a/docs/animation.html +++ b/docs/animation.html @@ -515,6 +515,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/components-and-props.html b/docs/components-and-props.html index 933f68f896..9b52d7a165 100644 --- a/docs/components-and-props.html +++ b/docs/components-and-props.html @@ -444,6 +444,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/composition-vs-inheritance.html b/docs/composition-vs-inheritance.html index 05e3acad31..079a2b738f 100644 --- a/docs/composition-vs-inheritance.html +++ b/docs/composition-vs-inheritance.html @@ -376,6 +376,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/conditional-rendering.html b/docs/conditional-rendering.html index 472b00cee1..76c58dc9e7 100644 --- a/docs/conditional-rendering.html +++ b/docs/conditional-rendering.html @@ -438,6 +438,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/context.html b/docs/context.html index 46b50f2994..5968e70dcd 100644 --- a/docs/context.html +++ b/docs/context.html @@ -420,6 +420,11 @@ You can do this directly in React with the powerful "context" API.

    +
  • + Accessibility + +
  • + diff --git a/docs/create-fragment.html b/docs/create-fragment.html index eeb611d48a..eaa99d3ff3 100644 --- a/docs/create-fragment.html +++ b/docs/create-fragment.html @@ -272,6 +272,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/dom-elements.html b/docs/dom-elements.html index 76dc3abdca..bb9b82b4a3 100644 --- a/docs/dom-elements.html +++ b/docs/dom-elements.html @@ -366,6 +366,11 @@ xmlLang xmlSpace y y1 y2 yChannelSelector z zoomAndPan +
  • + Accessibility + +
  • + diff --git a/docs/error-decoder.html b/docs/error-decoder.html index bdf8d5ab45..512897a24b 100644 --- a/docs/error-decoder.html +++ b/docs/error-decoder.html @@ -234,6 +234,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/events.html b/docs/events.html index 17726a9da1..d0efa0bda7 100644 --- a/docs/events.html +++ b/docs/events.html @@ -483,6 +483,11 @@ onTimeUpdate onVolumeChange onWaiting +
  • + Accessibility + +
  • + diff --git a/docs/forms.html b/docs/forms.html index a29c15d04d..d9acb4c408 100644 --- a/docs/forms.html +++ b/docs/forms.html @@ -449,6 +449,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/handling-events.html b/docs/handling-events.html index daa01eaed5..1a8b480d72 100644 --- a/docs/handling-events.html +++ b/docs/handling-events.html @@ -341,6 +341,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/hello-world.html b/docs/hello-world.html index 178d385db2..82cc89071a 100644 --- a/docs/hello-world.html +++ b/docs/hello-world.html @@ -246,6 +246,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/higher-order-components.html b/docs/higher-order-components.html index a394147080..2bfe37217f 100644 --- a/docs/higher-order-components.html +++ b/docs/higher-order-components.html @@ -238,10 +238,10 @@

    Resist the temptation to modify a component's prototype (or otherwise mutate it) inside an HOC.

    function logProps(InputComponent) {
    -  InputComponent.prototype.componentWillReceiveProps(nextProps) {
    +  InputComponent.prototype.componentWillReceiveProps = function(nextProps) {
         console.log('Current props: ', this.props);
         console.log('Next props: ', nextProps);
    -  }
    +  };
       // The fact that we're returning the original input is a hint that it has
       // been mutated.
       return InputComponent;
    @@ -586,6 +586,11 @@
                 
               
             
    +          
  • + Accessibility + +
  • +
    diff --git a/docs/installation.html b/docs/installation.html index e9281ba2aa..c74e3cf985 100644 --- a/docs/installation.html +++ b/docs/installation.html @@ -529,6 +529,11 @@ function selectTabForHashLink() { +
  • + Accessibility + +
  • + diff --git a/docs/integrating-with-other-libraries.html b/docs/integrating-with-other-libraries.html index 50b8dd59fb..ba9f10f1b5 100644 --- a/docs/integrating-with-other-libraries.html +++ b/docs/integrating-with-other-libraries.html @@ -615,6 +615,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/introducing-jsx.html b/docs/introducing-jsx.html index 8b3d3c1520..6c19ef3ed5 100644 --- a/docs/introducing-jsx.html +++ b/docs/introducing-jsx.html @@ -354,6 +354,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/jsx-in-depth.html b/docs/jsx-in-depth.html index e258e5d6a5..74ac7182d7 100644 --- a/docs/jsx-in-depth.html +++ b/docs/jsx-in-depth.html @@ -546,6 +546,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/lifting-state-up.html b/docs/lifting-state-up.html index bd8ce9de2b..b2e303399c 100644 --- a/docs/lifting-state-up.html +++ b/docs/lifting-state-up.html @@ -508,6 +508,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/lists-and-keys.html b/docs/lists-and-keys.html index 7390f6b93e..6d767b7aa1 100644 --- a/docs/lists-and-keys.html +++ b/docs/lists-and-keys.html @@ -478,6 +478,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/optimizing-performance.html b/docs/optimizing-performance.html index 1cc465471e..cd62b18f2a 100644 --- a/docs/optimizing-performance.html +++ b/docs/optimizing-performance.html @@ -555,6 +555,11 @@ This section is only relevant if you configure webpack directly.

    +
  • + Accessibility + +
  • + diff --git a/docs/perf.html b/docs/perf.html index 333cd0be24..23bbe198d8 100644 --- a/docs/perf.html +++ b/docs/perf.html @@ -345,6 +345,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/pure-render-mixin.html b/docs/pure-render-mixin.html index 2ef7016b53..35b3566c93 100644 --- a/docs/pure-render-mixin.html +++ b/docs/pure-render-mixin.html @@ -266,6 +266,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/react-api.html b/docs/react-api.html index ede6a9fefa..ccb3cb0b85 100644 --- a/docs/react-api.html +++ b/docs/react-api.html @@ -379,6 +379,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/react-component.html b/docs/react-component.html index 0592ca4750..4996f8a4e7 100644 --- a/docs/react-component.html +++ b/docs/react-component.html @@ -526,6 +526,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/react-dom-server.html b/docs/react-dom-server.html index 4c1abd3b61..ae9f30b8c4 100644 --- a/docs/react-dom-server.html +++ b/docs/react-dom-server.html @@ -82,7 +82,7 @@

    Overview

    -

    The ReactDOMServer class allows you to render your components on the server.

    +

    The ReactDOMServer object allows you to render your components on the server.

    diff --git a/docs/react-dom.html b/docs/react-dom.html index cc216a284e..3e2d86c993 100644 --- a/docs/react-dom.html +++ b/docs/react-dom.html @@ -299,6 +299,11 @@ and should be avoided because future versions of React may render components asy +
  • + Accessibility + +
  • + diff --git a/docs/react-without-es6.html b/docs/react-without-es6.html index 26fde5536a..39a8a4b80c 100644 --- a/docs/react-without-es6.html +++ b/docs/react-without-es6.html @@ -416,6 +416,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/react-without-jsx.html b/docs/react-without-jsx.html index 3878314fbf..055d15efcc 100644 --- a/docs/react-without-jsx.html +++ b/docs/react-without-jsx.html @@ -268,6 +268,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/reconciliation.html b/docs/reconciliation.html index 12d869e926..b329042633 100644 --- a/docs/reconciliation.html +++ b/docs/reconciliation.html @@ -354,6 +354,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/refs-and-the-dom.html b/docs/refs-and-the-dom.html index fbd328824c..b97cc2cb1d 100644 --- a/docs/refs-and-the-dom.html +++ b/docs/refs-and-the-dom.html @@ -418,6 +418,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/rendering-elements.html b/docs/rendering-elements.html index 6c0b7e3cb5..65e7c9b2ea 100644 --- a/docs/rendering-elements.html +++ b/docs/rendering-elements.html @@ -307,6 +307,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/shallow-compare.html b/docs/shallow-compare.html index 21e1f59846..c2930dd089 100644 --- a/docs/shallow-compare.html +++ b/docs/shallow-compare.html @@ -257,6 +257,11 @@ It does this by iterating on the keys of the objects being compared and returnin +
  • + Accessibility + +
  • + diff --git a/docs/shallow-renderer.html b/docs/shallow-renderer.html index b094f4b3b6..0422506576 100644 --- a/docs/shallow-renderer.html +++ b/docs/shallow-renderer.html @@ -278,6 +278,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/state-and-lifecycle.html b/docs/state-and-lifecycle.html index e3af2961fd..6abd699c6c 100644 --- a/docs/state-and-lifecycle.html +++ b/docs/state-and-lifecycle.html @@ -618,6 +618,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/test-utils.html b/docs/test-utils.html index d75a2b4a3f..baff8dead0 100644 --- a/docs/test-utils.html +++ b/docs/test-utils.html @@ -435,6 +435,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/thinking-in-react.html b/docs/thinking-in-react.html index b89f8c3b0c..001093e1e8 100644 --- a/docs/thinking-in-react.html +++ b/docs/thinking-in-react.html @@ -387,6 +387,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/two-way-binding-helpers.html b/docs/two-way-binding-helpers.html index 75fac6d5f2..294ae9786f 100644 --- a/docs/two-way-binding-helpers.html +++ b/docs/two-way-binding-helpers.html @@ -337,6 +337,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/typechecking-with-proptypes.html b/docs/typechecking-with-proptypes.html index e20bced688..81bfe16984 100644 --- a/docs/typechecking-with-proptypes.html +++ b/docs/typechecking-with-proptypes.html @@ -375,6 +375,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/uncontrolled-components.html b/docs/uncontrolled-components.html index 181f3dd800..9862f348d3 100644 --- a/docs/uncontrolled-components.html +++ b/docs/uncontrolled-components.html @@ -279,6 +279,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/update.html b/docs/update.html index be813167d6..79bd650089 100644 --- a/docs/update.html +++ b/docs/update.html @@ -313,6 +313,11 @@ +
  • + Accessibility + +
  • + diff --git a/docs/web-components.html b/docs/web-components.html index 1c0eada6c7..f9540a0704 100644 --- a/docs/web-components.html +++ b/docs/web-components.html @@ -269,6 +269,11 @@ You will need to manually attach event handlers to handle these events within yo +
  • + Accessibility + +
  • + diff --git a/img/docs/keyboard-focus.png b/img/docs/keyboard-focus.png new file mode 100644 index 0000000000..ec83f2846e Binary files /dev/null and b/img/docs/keyboard-focus.png differ