A presentation at DDD Adelaide in in Adelaide SA, Australia by Jess Budd
#DDDAdelaide @jessbudd4
Jess Budd @jessbudd4 Front-end developer Accessibility consultant Senior digital producer Meetup organiser
🤕 😭 🚶📱 @jessbudd4
% = 💵 @jessbudd4
@jessbudd4
😬 @jessbudd4
Are JavaScript frameworks bad for accessibility? @jessbudd4
“ Nothing in React prevents us from building accessible web apps - Leslie Cohn-Wein, Netlify @jessbudd4
What is web accessibility? @jessbudd4
Removing barriers that prevent people with disabilities using your website @jessbudd4
1 5 in Australians experience some form of disability Source: www.and.org.au/pages/disability-statistics.html @jessbudd4
357,000 Australians have a visual impairment Source: www.and.org.au/pages/disability-statistics.html @jessbudd4
1 in 6 Australians are affected by hearing loss Source: www.and.org.au/pages/disability-statistics.html @jessbudd4
Vision Hearing Mobility Cognitive @jessbudd4
Credit: Undraw and Ben Usher Smith @jessbudd4
Accessibility benefits everyone @jessbudd4
Who is most impacted?
Keyboard users
Screenreade r users
Semantic HTML @jessbudd4
Why does it matter? @jessbudd4
screenshot of link list @jessbudd4
// not very accessible card component <div class=”product”> <div class=“name”> Product name </div> <div class=”description”> Description of product </div> <div class=”button”>Add to cart</div> </div>
// more accessible card component <li> <h2> Product name </h2> <p> Description of product </p> <button>Add to cart</button> </li>
Divs are not buttons @jessbudd4
Give buttons some ❤ @jessbudd4
Semantic markup is good for SEO @jessbudd4
Fragments for valid html @jessbudd4
// not allowed render() { return ( <li>Hello</li> <li>World</li> ); }
// not allowed // solution??? render() { render() { return ( return (
<li>Hello</li> <div> <li>World</li> <li>Hello</li> ); <li>World</li> } </div> ); } 👎// fragments syntax render() { return ( <React.fragment> <li>Hello</li> <li>World</li> </React.fragment> ); }
Inputs & labels @jessbudd4
// label not linked to input <label> Dog breed: </label> <input type=”text” name=”breed” />
// explicitly linked label to input <label for=”uniqueId”> Dog breed: </label> <input id=”uniqueId” type=”text” name=”breed” />
// “for” becomes “htmlFor” in JSX <label htmlFor=”uniqueId”> Dog breed: </label> <input id=”uniqueId” type=”text” name=”breed” />
What if I can’t set a unique ID in advance? @jessbudd4
// implicitly linked label to input <label> Dog breed: <input type=”text” name=”breed”/> </label>
What if the design doesn’t have labels? @jessbudd4
// label hidden with css is still announced <label class=“sr-only“ for=“dogBreed”> Dog breed: </label> <input id=“dogBreed” type=”text” name=”breed” />
// visually hidden, but accessible to screen readers .sr-only { clip: rect(1px, 1px, 1px, 1px); clip-path: inset(5%); height: 1px; width: 1px; margin: -1px; overflow: hidden; padding: 0; white-space: nowrap; position: absolute; border: 0; }
Touch target @jessbudd4
Page titles @jessbudd4
Click to edit
// page title appears in browser tab <head> <meta charset=”utf-8”> <title>Dogs Are The Best</title> <link rel=”stylesheet” href=”style.css”> </head>
// code executes when component mounts componentDidMount() { document.title = ‘Heckin’ Good Doggo’; }
// update page title on routing componentDidMount() { document.title = ‘Heckin’ Good Doggo’; }
Update <head> elements React Helmet @jessbudd4
Click to edit
Visible focus styles @jessbudd4
Default browser styles Safari: Firefox: Chrome: @jessbudd4
Meme where am I @jessbudd4
Screen shot of page with masses of links and question marks ??? @jessbudd4
/* don’t just remove */ *:focus { outline: none; } ❌
/* don’t just remove */ :focus { outline: none; ❌ } / replace with something! */ :focus { / branded focus styles here */ border: 2px dotted currentColor; } ✅
/* extend hover styles */ .button:hover, .button:focus { border: 5px solid #33ffdb; }
Focus management @jessbudd4
Tabindex Explained // tabindex becomes tabIndex (camelCase) in JSX tabindex=”0” // makes element focusable in tab/DOM order tabindex=”-1” // makes elements focusable only via scripting tabindex=”5” // Danger Will Robinson!
React has silent routing @jessbudd4
Video of default browser behaviour @jessbudd4
Move keyboard focus on routing @jessbudd4
Use an accessible router Reach/Router @jessbudd4
Use React Refs @jessbudd4
class PageHeading extends React.Component { constructer(props) { super(props); this.content = React.createRef(); // Create Ref } componentDidMount() { this.content.focus(); // Move focus to ref } render() { return ( <h1 tabindex=”-1” ref={this.content}> // Reference Doggos, Puppers and Floofers </h1> ); } }
class PageHeading extends React.Component { constructer(props) { super(props); this.content = React.createRef(); // Create Ref } componentDidMount() { this.content.focus(); // Move focus to ref } render() { return ( <h1 tabindex=”-1” ref={this.content}> // Reference Doggos, Puppers and Floofers </h1> ); } }
class PageHeading extends React.Component { constructer(props) { super(props); this.content = React.createRef(); // Create Ref } componentDidMount() { this.content.focus(); // Move focus to ref } render() { return ( <h1 tabindex=”-1” ref={this.content}> // Reference Doggos, Puppers and Floofers </h1> ); } }
// update page title // and move users focus componentDidMount() { document.title = ‘Doggos be happy’; this.content.focus(); }
Modals have specific focus challenges @jessbudd4
Use an accessible modal react-modal @jessbudd4
Tooling @jessbudd4
eslint-plugin-jsx-a11y eslint-plugin-jsx-a11y @jessbudd4
Axe-core react-axe @jessbudd4
Accessibility Tree (Dev Tools) @jessbudd4
Google Lighthouse https://developers.google.com/web/tools/lighthouse @jessbudd4
Accessibility Insights https://accessibilityinsights.io/ @jessbudd4
https://www.matuzo.at/blog/building-the-most-inaccessible-site-possible-with-a-perfect-lighthouse-score/
“ Automated testing is just the first step - Manuel Matuzovic @jessbudd4
Testing @jessbudd4
Keyboard @jessbudd4
What to look for Can I see where focus is? Does the tab order make sense? Can I access all required elements? Can I use advanced components? Does my focus move when needed? @jessbudd4
Screenreader @jessbudd4
Voiceover (macOS) NVDA (Windows) JAWS (Windows) 💰 @jessbudd4
😎 @jessbudd4
@jessbudd4
Recommended Resources @jessbudd4
React Documentation https://reactjs.org/docs/accessibility.html @jessbudd4
Front End Masters Course https://frontendmasters.com/courses/javascript-accessibility/ @jessbudd4
Inclusive Components https://inclusive-components.design/ @jessbudd4
Scott Vinkle https://scottvinkle.me/ @jessbudd4
Takeaways Use Semantic HTML Link form labels with inputs Update page titles on routing Manage keyboard focus Use tooling & test your apps @jessbudd4
Go forth and make the web a better place @jessbudd4
Thanks! Slides at bit.ly/DDDA19 @jessbudd4
Javascript frameworks get a bad rap when it comes to accessibility. But is it the frameworks creating the barriers, or us as the developers?
Follow me on a React journey through div soup, past the lost focus and under the unchanged titles. Find out: is there actually anything in React preventing us from building accessible web apps? You’ll get a high level overview of fundamental issues, how to address them, and how to ensure your website is accessible and inclusive to all.
The following resources were mentioned during the presentation or are useful additional information.
Official accessibility documentation for React.js
Here’s what was said about this presentation on social media.
Been waiting for this one, @jessbudd4 talking about accessibility at #DDDAdelaide 😄 pic.twitter.com/l9UcHM4EgR
— Jakob Pennington @ DDD Adelaide (@JakobTheDev) November 23, 2019
My phone was flat so I couldn't livetweet, but IMO @jessbudd4's talk was one of the best I saw all day #DDDAdelaide https://t.co/gLzYmkMzQI
— Leigh Brenecki @ #DDDAdelaide (@excitedleigh) November 23, 2019
@jessbudd4 I planned to live tweet that talk but I was too captivated to look down at my phone. Great talk!
— Scott Cabot (@thescottcabs) November 23, 2019
'People in the disability community are amplifiers and fans for life. If they have a good experience they tell everyone.' - @jessbudd4 @DDDAdelaide #DDDAdelaide pic.twitter.com/z8CHDRulzZ
— Ming Johanson 👉 speaking at #DDDAdelaide (@MingJohanson) November 23, 2019
Great stuff from @jessbudd4 #DDDAdelaide
— Dan Harris 👉 #DDDAdelaide (@danharris_io) November 23, 2019
You're leaving money on the table if you're not considering 20% of the population - great point made by both @thescottcabs and @jessbudd4 on the business case for making your software accessible #DDDAdelaide pic.twitter.com/VM1lngDIr5
— Jakob Pennington @ DDD Adelaide (@JakobTheDev) November 23, 2019
Heckin good talk from @jessbudd4 on @reactjs #a11y 👌 #DDDAdelaide
— Dan Harris 👉 #DDDAdelaide (@danharris_io) November 23, 2019
Fabulous talk @jessbudd4 - really appreciated it - you were excellent - and I definitely learned things I'm going to start looking for in apps 😊 #DDDAdelaide
— Lyndsey Jackson (@ok_lyndsey) November 23, 2019
Such a great talk Jess, so much clear, actionable information! 👏🙌
— Melissa Kyd 👩💻 #dddAdelaide (@melissa_kyd) November 24, 2019
Finishing on a positive note, @jessbudd4 tasks us all to for forth and make the web a better place 🤗 #DDDAdelaide pic.twitter.com/Z8QGVswtKe
— Amy @ #DDDAdelaide (@Amys_Kapers) November 23, 2019
Accessibility in React (and JavaScript) is easier than you think. @jessbudd4 is sharing how we can improve our apps for everyone in Room 2 @DDDAdelaide #DDDAdelaide pic.twitter.com/19LWjdPJqm
— Ian Hughes (@ian_hughes) November 23, 2019