git clone
https://github.com/ericmasiello/accessibility-demo.git
cd accessibility-demo
npm install
(Demo)
Tabs are not a native web paradigm. They come from desktop interfaces.
<div className="tablist">
<div className="tab">Tab name</div>
...
</div>
<div className="tablist">
<div className="tab">Tab name</div>
<button className="tab">Tab name</button>
...
</div>
git checkout 02-basic-keyboard-focus
button:focus,
a:focus {
/* Don't do this without adding back a focus state! */
outline: none;
}
https://www.w3.org/TR/wai-aria-practices/#tabpanel
git checkout 03-proper-tab-keyboard-controls
{diamonddogs.map(member => ( <button tabIndex={tabState.selected !== member.id ? -1 : undefined} ref={tabState.selected === member.id && tabState.selectedTabRef} onKeyDown={tabState.handleTabKeyDown} onClick={() => { tabState.setSelected(member.id); }} className={classNames(['tab', {'tab--selected': tabState.selected === member.id }])} > {member.name} </button> ))}
<section ref={tabState.panelRef} tabIndex={0}>
...
</section>
handleKeyDown = event => { switch (event.which) { case KEYS.right: { this.setState({ selected: findNext( this.props.tabIds, this.state.selected ) }, () => { this.state.selectedTabRef.current.focus(); }); break; } case KEYS.left: { // ...
handleKeyDown = event => { switch (event.which) { // ... case KEYS.down: { this.state.panelRef.current.focus(); break;
// ...
<title>Diamond Dog Team Page</title>
<h1 className="page-title">Diamond Dogs</h1>
<img
className="bio-photo"
src={selectedMember.photo}
alt={selectedMember.photoDesc}
/>
git checkout 04-additional-html-semantics
<dl className="bio"> <dt className="bio__label">Hometown</dt> <dd className="bio__item">{selectedMember.hometown}</dd> <dt className="bio__label">Time at Vistaprint</dt> <dd className="bio__item">{selectedMember.employment}</dd> <dt style={{ display: "none" }}>Biography</dt> <dd className="bio__item">{selectedMember.bio}</dd> </dl>
<dt style={{ display: "none" }}>Biography</dt>
display: none; is not announced by screen reader
<dt className="visually-hidden">Biography</dt>
.visually-hidden {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
white-space: nowrap;
}
HTML lacks all the necessary elements to accurately describe our app to assistive technology
Accessible Rich Internet Applications: supplements HTML with additional roles, attributes, and states to describe UI widgets
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA
<div role="tablist" className="tablist" aria-label="Team members">
git checkout 05-aria
<button
role="tab"
aria-selected={tabState.selected === member.id}
aria-controls={tabState.selected === member.id
? 'tab-panel'
: undefined
}
...
<section
ref={tabState.panelRef}
id="tab-panel"
tabIndex={0}
role="tabpanel"
aria-label={selectedMember.name}
>
There’s really no right or wrong in inclusive design. It’s just about trying your hardest to provide a valuable experience to as many people as you can... no matter how they are operating or reading your interface...
Other considerations: