This is the 27th day of my participation in Gwen Challenge

What is accessibility?

Official description: Accessibility (also known as A11Y because it begins with A, ends with Y, and has 11 letters in it) is A design and creation that helps everyone gain access to services. Accessibility is a necessary condition for assistive technology to correctly interpret web pages.

Interpretation of the

Accessibility refers to the design and creation of services that help all people access them.

Standards and Guidelines

WCAG

The Web Content Accessibility Guidelines (WCAG) provide Guidelines for developing accessible websites.

WAI-ARIA

The Web Accessibility Initiative – Accessible Rich Internet Applications file contains JavaScript for creating fully Accessible JavaScript The technology required for the component.

Interpretation of the

While most DOM variable and attribute names in React use camel’s back nomenclature, JSX supports all ARIA -* HTML attributes in terms of accessibility accessibility. Aria -* should be hyphenated as it is in HTML.

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

Semantic HTML

Official description: Semantic HTML is the foundation of accessibility web applications. Using multiple HTML elements to enhance the information in your site often gives you direct access to accessibility features.

  • Sometimes semantic HTML is broken by elements such as div, UL, OL, table, etc. We can use React Fragments to combine components.
  • For example,
import React, { Fragment } from 'react';

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

function Glossary(props) {
  return (
    <dl>
      {props.items.map(item => (
        <ListItem item={item} key={item.id} />
      ))}
    </dl>
  );
}
Copy the code
  • When you don’t need to add any prop to the Fragment tag and your tool supports it, you can use phrases like the following:
function ListItem({ item }) {
  return (
    <>
      <dt>{item.term}</dt>
      <dd>{item.description}</dd>
    </>
  );
}
Copy the code

Accessible forms

tag

Official description: All HTML form controls, such as <input> and <textarea>, need to be annotated for accessibility accessibility. We need to provide screen readers for explanatory annotation.

  • Official note: Please note that for in JSX should be written htmlFor:
<label htmlFor="namedInput">Name:</label>
<input id="namedInput" type="text" name="name"/>
Copy the code

Alert users when errors occur

Official description: When an error occurs, all users should be informed. The following link tells us how to set error messages for the screen reader:

W3C presents user push

Control the focus

Make sure your web application works even with a keyboard.

Keyboard focus and focus profile

Official definition: In the DOM, the element currently selected to receive keyboard information. We can see the keyboard focus here and there, and it will be surrounded by the focus outline, like the image below.

Skip content mechanism

Interpretation of the

The skip content mechanism is a hidden navigation link that is only visible when using the keyboard to navigate. It’s easy to do this using internal anchors and a few styles. Think of Github’s anchor jump for some articles, something like that.

Use programs to manage focus

  • Why use programs to manage focus?

Our React app keeps changing the HTML DOM as it runs, sometimes causing keyboard focus to be lost or set to unexpected elements. To fix this, we need to programmatically focus the keyboard in the right direction. For example, when a popover is closed, reset the keyboard focus to the popover’s open button.

  • Implementation steps
  1. Start by creating an element ref in the JSX of a class component
class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    // Create a textInput DOM element ref
    this.textInput = React.createRef();
  }
  render() {
  // Use the 'ref' callback to store the text input DOM element in a variable of the instance
  // (for example, this.textinput).
    return (
      <input
        type="text"
        ref={this.textInput}
      />); }}Copy the code
  1. Focus on this component elsewhere as needed
focus() {
  Use the original DOM API to explicitly focus on the text input
  // Note: we get the DOM node by accessing "current"
  this.textInput.current.focus();
}
Copy the code
  1. Sometimes a parent component needs to focus on an element of its child component. We can have the parent component pass the REF to the child component via props
function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} />
    </div>
  );
}

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.inputElement = React.createRef();
  }
  render() {
    return (
      <CustomTextInput inputRef={this.inputElement} />); }}// Now you can set the focus as needed
this.inputElement.current.focus();
Copy the code

Official note: While this is a very important accessibility feature, it is also a technology that should be used with caution. Instead of trying to predict how the user wants to use the application, we should use it to fix keyboard focus when we are disturbed.

Mouse and pointer events

Make sure that anything that can be done with a mouse and pointer can also be done with the keyboard alone. Relying on Pointers alone can create a lot of situations where keyboard users can’t use your application.

A typical example of breaking accessibility caused by a click event: external click mode, where the user can close an open pop-up box by clicking outside of the element.

  • Method: Add a click event to the window object
class OuterClickExample extends React.Component {
  constructor(props) {
    super(props);

    this.state = { isOpen: false };
    this.toggleContainer = React.createRef();

    this.onClickHandler = this.onClickHandler.bind(this);
    this.onClickOutsideHandler = this.onClickOutsideHandler.bind(this);
  }

  componentDidMount() {
    window.addEventListener('click'.this.onClickOutsideHandler);
  }

  componentWillUnmount() {
    window.removeEventListener('click'.this.onClickOutsideHandler);
  }

  onClickHandler() {
    this.setState(currentState= > ({
      isOpen: !currentState.isOpen
    }));
  }

  onClickOutsideHandler(event) {
    if (this.state.isOpen && !this.toggleContainer.current.contains(event.target)) {
      this.setState({ isOpen: false}); }}render() {
    return (
      <div ref={this.toggleContainer}>
        <button onClick={this.onClickHandler}>Select an option</button>
        {this.state.isOpen && (
          <ul>
            <li>Option 1</li>
            <li>Option 2</li>
            <li>Option 3</li>
          </ul>
        )}
      </div>); }}Copy the code
  • Problems with the above approach

When using only the keyboard, because the window object does not receive the click event, the user cannot use the TAB to move to the next element. This can lead to users not being able to use some of the content in your app, leading to an incomplete user experience.

  • Using the right event triggers, such as onBlur and onFocus, solves this problem
class BlurExample extends React.Component {
  constructor(props) {
    super(props);

    this.state = { isOpen: false };
    this.timeOutId = null;

    this.onClickHandler = this.onClickHandler.bind(this);
    this.onBlurHandler = this.onBlurHandler.bind(this);
    this.onFocusHandler = this.onFocusHandler.bind(this);
  }

  onClickHandler() {
    this.setState(currentState= > ({
      isOpen: !currentState.isOpen
    }));
  }

  // At the next point in time we use setTimeout to close the popover.
  // This is necessary because out-of-focus events are triggered before new focus events,
  // We need to identify a child node of this element through this step
  // Whether you get focus.
  onBlurHandler() {
    this.timeOutId = setTimeout(() = > {
      this.setState({
        isOpen: false
      });
    });
  }

  // If a child node gets focus, do not close the popover.
  onFocusHandler() {
    clearTimeout(this.timeOutId);
  }

  render() {
    React transmits out-of-focus and out-of-focus events to the parent node
    // Come and help us.
    return (
      <div onBlur={this.onBlurHandler}
           onFocus={this.onFocusHandler}>
        <button onClick={this.onClickHandler}
                aria-haspopup="true"
                aria-expanded={this.state.isOpen}>
          Select an option
        </button>
        {this.state.isOpen && (
          <ul>
            <li>Option 1</li>
            <li>Option 2</li>
            <li>Option 3</li>
          </ul>
        )}
      </div>); }}Copy the code
  • Note: Aria -* props was officially used to serve screen reader users.

More complex parts

A more complex user experience does not mean that it is more difficult to access. By programming as close to HTML as possible, accessibility is made easier and accessible to even the most complex parts.

Welcome to learn React!