Manuel Matuzovi Frontend Developer from Vienna HTML, CSS, - - PowerPoint PPT Presentation

manuel matuzovi
SMART_READER_LITE
LIVE PREVIEW

Manuel Matuzovi Frontend Developer from Vienna HTML, CSS, - - PowerPoint PPT Presentation

Manuel Matuzovi Frontend Developer from Vienna HTML, CSS, Accessibility twitter: @mmatuzo bit.ly/react-tips @mmatuzo 12 Tips For More Accessible React Apps @mmatuzo 8 12 Tips For More Accessible React Apps @mmatuzo a11y tip #1


slide-1
SLIDE 1
slide-2
SLIDE 2

Manuel Matuzović

Frontend Developer from Vienna HTML, CSS, Accessibility twitter: @mmatuzo

slide-3
SLIDE 3

bit.ly/react-tips

@mmatuzo

slide-4
SLIDE 4

12 Tips For More Accessible React Apps

@mmatuzo

slide-5
SLIDE 5

12 Tips For More Accessible React Apps

8

@mmatuzo

slide-6
SLIDE 6

@mmatuzo

a11y tip #1

Create a sound document outline.

slide-7
SLIDE 7

@mmatuzo

a11y tip #1

<h1>Yo! I'm the title of your page.<0h1> <h2>I'm very important.<0h2> <h3>My parent is very important.<0h3> <h3>My parent is very important.<0h3> <h4>I exist.<0h4> <h2>I'm very important.<0h2> <h3>My parent is very important.<0h3>

slide-8
SLIDE 8
slide-9
SLIDE 9

@mmatuzo

a11y tip #1

<Heading.H>I will be an h1<0Heading.H> <Heading.LevelBoundary> <Heading.H>I will be an h2<0Heading.H> <Heading.LevelBoundary> <Heading.H>I will be an h3<0Heading.H> <0Heading.LevelBoundary> <Heading.H>I will be an h2<0Heading.H> <0Heading.LevelBoundary>

slide-10
SLIDE 10

@mmatuzo

a11y tip #1

<h1>I will be an h1<0h1> <h2>I will be an h2<0h2> <h3>I will be an h3<0h3> <h2>I will be an h2<0h2>

slide-11
SLIDE 11
slide-12
SLIDE 12

@mmatuzo

Create a sound document

  • utline.

<h1>React Finland.<0h1> <h2>MCs<0h2> <h2>Speakers<0h2> <h2>Sponsors<0h2> <h3>Gold Sponsors<0h3> <h3>Silver Sponsors<0h3> <h3>Bronze Sponsors<0h3>

a11y tip #1

  • It gives your document structure.
  • Helps screen reader users with

navigation.

  • Important for SEO.
  • Check out Tenon UI's headings

component.

  • Test your document outline with tota11y
  • r wave.

@mmatuzo

slide-13
SLIDE 13

@mmatuzo

a11y tip #2

Hide content correctly

slide-14
SLIDE 14
slide-15
SLIDE 15

display: none; visibility: hidden; hidden attribute

@mmatuzo

slide-16
SLIDE 16

display: none; visibility: hidden; hidden attribute

@mmatuzo

slide-17
SLIDE 17

@mmatuzo

a11y tip #2

.visually-hidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px;

  • verflow: hidden;

padding: 0; position: absolute; width: 1px; white-space: nowrap; }

slide-18
SLIDE 18

@mmatuzo

<h1>React Finland.<0h1> <h2>MCs<0h2> <h2>Speakers<0h2> <h2 className="visually-hidden"> Sponsors <0h2> <h3>Gold Sponsors<0h3> <h3>Silver Sponsors<0h3> <h3>Bronze Sponsors<0h3>

@mmatuzo

slide-19
SLIDE 19

@mmatuzo

a11y tip #2

<button> <span class="visually-hidden">Save<0span> <svg aria-hidden="true" width="32" height="32"> <path …><0path> <0svg> <0button>

slide-20
SLIDE 20

@mmatuzo

a11y tip #2

<button> <VisuallyHidden>Save<0VisuallyHidden> <svg aria-hidden="true" width="32" height="32"> <path …><0path> <0svg> <0button>

https://github.com/reach/reach-ui/tree/master/packages/visually-hidden

slide-21
SLIDE 21

@mmatuzo

Hide content correctly

.visually-hidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px;

  • verflow: hidden;

padding: 0; position: absolute; width: 1px; white-space: nowrap; }

a11y tip #2

  • display: none; visibility:

hidden; and the hidden attribute

remove content from the accessibility tree.

  • Every item needs a textual

representation, even if it isn't visible.

  • Check out Reach UI's VisuallyHidden

component.

@mmatuzo

slide-22
SLIDE 22

@mmatuzo

a11y tip #3

Use <button> if you need a button

slide-23
SLIDE 23

@mmatuzo

<button className="btn"

  • nClick={this.handleClick}>

I'm a real button <0button>

@mmatuzo

slide-24
SLIDE 24

@mmatuzo

<div className="btn"

  • nClick={this.handleClick}>

I'm a wannabe <0div>

@mmatuzo

slide-25
SLIDE 25

@mmatuzo

Use <button> if you need a button

<button> ❤ <0button>

a11y tip #3

  • <button>s are focusable by default.
  • They come with keyevents for free.
  • <button>s are semantic. A <div> is

just generic text.

  • Check out Just use button by Rob

Dodson and The Links vs. Buttons Showdown by Marcy Sutton on YouTube.

@mmatuzo

slide-26
SLIDE 26

@mmatuzo

a11y tip #4

Use fragments to avoid invalid HTML

slide-27
SLIDE 27

@mmatuzo

a11y tip #4

const Table = props =? { return ( <table> <tr> <Columns /? <0tr> <0table> ); }

slide-28
SLIDE 28

@mmatuzo

a11y tip #4

const Columns = props =? { return ( <div> <td>Hello<0td> <td>World<0td> <0div> ); }

slide-29
SLIDE 29

@mmatuzo

a11y tip #4

<table> <tr> <div> <td>Hello<0td> <td>World<0td> <0div> <0tr> <0table>

☠ 🚩

slide-30
SLIDE 30

@mmatuzo

a11y tip #4

const Columns = props =? { return ( <React.Fragment> <td>Hello<0td> <td>World<0td> <0React.Fragment> ); }

slide-31
SLIDE 31

@mmatuzo

a11y tip #4

<table> <tr> <td>Hello<0td> <td>World<0td> <0tr> <0table>

🥱 🎊

slide-32
SLIDE 32

@mmatuzo

Use fragments to avoid invalid HTML

function Columns() { return ( <? <td>Hello<0td> <td>World<0td> </? ); }

a11y tip #4

  • Fragments help you write valid HTML.
  • They reduce bloat.
  • There's also a shorter syntax (see code

example ➡)

  • Check out the Fragments docs for more

details and examples.

@mmatuzo

slide-33
SLIDE 33

@mmatuzo

a11y tip #5

Take care of focus management.

slide-34
SLIDE 34
slide-35
SLIDE 35
slide-36
SLIDE 36

@mmatuzo

a11y tip #5

class Button2 extends React.Component { constructor(props) { super(props); this.btn = React.createRef(); } setFocus(){ this.btn.current.focus(); } render() { return ( <button className="btn" ref={ this.btn }> { this.props.children } <0button> ) } }

slide-37
SLIDE 37
slide-38
SLIDE 38

@mmatuzo

Take care of focus management.

class CustomTextInput extends React.Component { constructor(props) { super(props); /0 Create a ref to store the textInput DOM element this.textInput = React.createRef(); } render() { /0 Use the `ref` callback to store a reference to the text input DOM /0 element in an instance field (for example, this.textInput). return ( <input type="text" ref={this.textInput} /? ); } }

a11y tip #5

  • Focus management is important

because it's essential for keyboard and screen reader users.

  • Take advantage of refs in React to

manage focus.

  • Check out the A11y dialog on Github

and the accessibility docs on reactjs.org.

@mmatuzo

slide-39
SLIDE 39

@mmatuzo

a11y tip #6

Make notifications accessible to everyone

slide-40
SLIDE 40
slide-41
SLIDE 41

@mmatuzo

a11y tip #5

<div className="alert" role="alert"> Saved successfully <0div>

slide-42
SLIDE 42
slide-43
SLIDE 43

@mmatuzo

Make notifications accessible to everyone

<div className="alert" role="alert"> Saved successfully <0div> /0 alert will interrupt the screen reader if it's in the course of announcing something else. <div className="alert" role="status"> Saved successfully <0div> /0 status will wait until the screen reader has finished announcing. <div className="alert" role="alert" aria- atomic="true"> Saved successfully <span>I will be announced as well<0span> <0div> /0 aria-atomic="true" - annouces everything not just the content that has changed.

a11y tip #6

  • Use role="alert" or role="status"

to create live regions.

  • Use live regions only for important

information.

  • Check out Reach UI's alert component.
  • Check out react-aria-live on Github.
  • Read ARIA live regions in React on

Almero Steyns blog.

@mmatuzo

slide-44
SLIDE 44

@mmatuzo

a11y tip #7

Announce page changes

slide-45
SLIDE 45
slide-46
SLIDE 46
slide-47
SLIDE 47

@mmatuzo

a11y tip #7

class About extends React.Component { constructor(props) { super(props); this.section = React.createRef(); } componentDidMount(){ this.section.current.focus(); document.title = "About"; } render() { return ( <section tabIndex="-1" ref={ this.section }> <h2>About<0h2><p>We are…<0p><p>Lorem ipsum…<0p> <0section> ) } }

slide-48
SLIDE 48

@mmatuzo

a11y tip #7

render() { return ( <section aria-labelledby="pageTitle" tabIndex="-1" ref= { this.section }> <h2 id="pageTitle">About<0h2> <p>We are…<0p><p>Lorem ipsum…<0p> <0section> ) }

slide-49
SLIDE 49
slide-50
SLIDE 50

@mmatuzo

Reach Router

a11y tip #7

  • Keyboard accessible.
  • Assistive devices announce changes.
  • Cmd/Ctrl click opens in a new tab.
  • Right click “open in new window” opens in a new window.
  • Out-of-the-box focus management.

https://reach.tech/router

@mmatuzo

slide-51
SLIDE 51

@mmatuzo

Announce page changes

class Blog extends React.Component { constructor(props) { super(props); this.heading = React.createRef(); } componentDidMount(){ this.heading.current.focus(); document.title = "Blog"; } render() { return ( <section aria-labelledby="pageTitle" tabIndex="-1" ref= { this.heading }> <h2 id="pageTitle">Blog<0h2><p>My blog…<0p> <0section> ) } }

a11y tip #7

  • Announce page changes.
  • Use refs to manage focus.
  • If necessary, make items focusable by

applying tabindex="-1"

  • Check out Reach Router.

@mmatuzo

slide-52
SLIDE 52

@mmatuzo

a11y tip #8

Test your React code automatically

slide-53
SLIDE 53

@mmatuzo

a11y tip #5

var React = require('react'); var ReactDOM = require('react-dom'); if (process.env.NODE_ENV !=> 'production') { var axe = require('react-axe'); axe(React, ReactDOM, 1000); }

slide-54
SLIDE 54
slide-55
SLIDE 55

@mmatuzo

Test your React code automatically

var React = require('react'); var ReactDOM = require('react-dom'); if (process.env.NODE_ENV !=> 'production') { var axe = require('react-axe'); axe(React, ReactDOM, 1000); }

a11y tip #8

  • Automatic tests help you notice low

hanging fruits.

  • Automatic testing is only the first step.

Manual testing is necessary.

  • Check out React-axe and eslint-plugin-

jsx-a11y on Github.

@mmatuzo

slide-56
SLIDE 56

Kiitos!

@mmatuzo

💖 💖

bit.ly/react-tips