0
votes

I have following issue. Let say I have component Loading with following props loadContext.

Normally I have button with text "load more" and when user click on it appears spinner (Loading component) and then it's loaded next content on the web page.

but this code is just simplified version and button contains spinner. The screen reader reads <button> and <a> html tag but no Loading component.

<button>
  <a href="#"> 
  <Loading loadContext="browser is loaded context" />
  </a>
</button>

Loading component:

 export default class Loading extends React.Component {

      static get propTypes() {
        return {
          loadContext: React.PropTypes.string.isRequired,
        };
      }

      shouldComponentUpdate() {
        return false;
      }

      render() {
        const els = [];

        if(this.props.loadContext) {
          els.push(<span  role="status"   key="read-context" className="loader-context-hidden"> {this.props.loadContext}</span>);
        }
    els.push(<div className="loading__inner" key="loading__inner"></div>);

        const maybeDelay = (children) => {
          if (typeof this.props.delay === 'number') {
            return (
              <Delay wait={this.props.delay}>
                {children}
              </Delay>
            );
          }
          return children;
        };
        return maybeDelay(
          <div className={[ 'loading' ].concat(extraClassNames).join(' ')}>
            {els}
          </div>
        );
      }
    }

What I want to do: If user click on the button then screen reader will read the text from passed prop loadContext in span tag.

The span tag with the text from prop loadContext has class loader-context-hidden (what means visibility:hidden in css file).

Rendered loading component:

<Loading loadContext="the browser is loading new context">
  <div className="loading"
    <span key="read-context" role="status" className="loader-context-hidden">{this.props.loadContext} </span>
  <div key="loading_inner" className="loading__inner"> </div>     
 </Loading>

Question: How can I achieve that screen reader look into Loading component and will read text in span tag. I have to use role="status" from aria.

1

1 Answers

2
votes

You say:

The span tag with the text from prop loadContext has class loader-context-hidden (what means visibility:hidden in css file).

Don't use visibility: hidden. It will make it invisible to a screen reader. That goes for display: none as well. Instead use a style that will position the element in such a way that it is still considered "visible" but is invisible for all intents and purposes.

See WebAIM's article: Invisible Content Just for Screen Reader Users.

The article suggests using a utility style similar to the following:

.hidden {
    position:absolute;
    left:-10000px;
    top:auto;
    width:1px;
    height:1px;
    overflow:hidden;
}