Slide 1
CSS, JavaScript, & Accessibility Ire Aderinokun @ An Event Apart Spring Summit 2022
Slide 2
“By default, HTML is accessible. Web accessibility involves ensuring that content remains accessible.” https://developer.mozilla.org/en-US/docs/Learn/Accessibility
Slide 3
Web accessibility is the inclusive practice of ensuring there are no barriers that prevent access to websites
Slide 4
Slide 5
Slide 6
Socio-economic restrictions
Slide 7
Accessibility is about inclusion
Slide 8
Slide 9
- Content must be perceivable 🧏
Slide 10
- Interface must be operable 🛠
Slide 11
- Content must be understandable 📖
Slide 12
Slide 13
“By default, HTML is accessible, if used correctly. Web accessibility involves ensuring that content remains accessible.” https://developer.mozilla.org/en-US/docs/Learn/Accessibility
Slide 14
Slide 15
<main> <h1>Page Heading</h1> <p>Other less important text</p> </main>
Slide 16
In the absence of other languages, we have to use HTML correctly
Slide 17
https://ireade.github.io/motherduckingwebsite/
Slide 18
https://ireade.github.io/motherduckingwebsite/
Slide 19
By default, HTML is perceivable 🧏
Slide 20
Guideline 1.3 — Create content that can be presented in different ways ✅
Slide 21
Guideline 1.4 — Make it easier for users to see and hear content including separating foreground from background ✅
Slide 22
By default, HTML is operable 🛠
Slide 23
Guideline 2.1 — Make all functionality available from a keyboard ✅ Guideline 2.5 — Make it easier for users to operate functionality through various inputs beyond keyboard ✅
Slide 24
By default, HTML is understandable 📖
Slide 25
Guideline 3.2 — Make Web pages appear and operate in predictable ways ✅
Slide 26
Guideline 3.3 — Help users avoid and correct mistakes ✅
Slide 27
By default, HTML is robust ⚙
Slide 28
By default, HTML is robust, if used correctly ✅
Slide 29
Slide 30
Missing text alternatives ☹
<img src=“link/to/really-important-image.png”
Slide 31
Using the wrong elements ☹
<p>Enter your username:</p> <input type=“text”>
Slide 32
Weird tab order ☹
<ul> <li><a href=“/one” tabindex=“2”>Link One</a></li> <li><a href=“/two” tabindex=“3”>Link Two</a></li> <li><a href=“/three” tabindex=“1”>Link Three</a></li> </ul>
Slide 33
Slide 34
Slide 35
Adding content with CSS ☹
<div id=“important”></div>
#important
after {
content: “Really important information that everyone should know”
:
:
}
Slide 36
Altering element behaviour with JavaScript ☹
<div onClick=“goToPage(‘/about’)”> About Us </div>
Slide 37
90% of accessibility is about using HTML correctly. The other 10% is about not using CSS/JS incorrectly.
Slide 38
CSS, JavaScript, & Accessibility
Slide 39
Part One
CSS & Accessibility
Slide 40
CSS is used to describe the presentation of an HTML document
Slide 41
Slide 42
Slide 43
DOM <head> <title>Understanding the Critical Rendering Path</title> <link rel=”stylesheet” href=”style.css”> </head> <body> <header> <h1>Understanding the Critical Rendering Path</h1> </header> <main> <h2>Introduction</h2> <p>Lorem ipsum dolor sit amet</p> </main> <footer><small>Copyright 2017</small></footer> </body>
Slide 44
CSSOM body { font-size: 18px; }
header { color: plum; } h1 { font-size: 28px; }
main { color: firebrick; } h2 { font-size: 20px; }
footer { display: none; }
Slide 45
DOM + CSSOM - Non-visible elements = Render tree
Slide 46
Slide 47
Slide 48
AOM <form> <p>Make a choice:</p> <input type=“radio” name=“choice” id=“yes” /> <label>Yes</label> <input type=“radio” name=“choice” id=“no” /> <label>No</label>
<input type=“checkbox” name=“agree” id=“agree” /> <label>I agree</label> </form>
Slide 49
Slide 50
Slide 51
#1
Don’t use CSS to convey meaning or content
Slide 52
h1
after { content: “My Page Title”
:
:
}
Slide 53
https://tink.uk/accessibility-support-for-css-generated-content/
Slide 54
“In other words, use CSS generated content to change or supplement the design, but not to create or alter important content on the page.”
— Léonie Watson https://tink.uk/accessibility-support-for-css-generated-content/
Slide 55
❌
✅
.element
after {
content:
.element
any content
content: “”
/
*
*
/
:
:
:
}
:
}
after {
Slide 56
<input class=“error” > <input class=“success” >
.error { border-color: red; } .success { border-color: green; }
Slide 57
<p>Price:</p> <span class=“strike”>$50</span> <span>$5,000</span>
.strike { text-decoration: line-through; }
Slide 58
#2
Don’t use CSS to change the semantics of HTML
Slide 59
❌
✅
This is <span class=“emphasise”>really</span> important
.emphasise { font-style: italic; }
This is <em>really</em> important
Slide 60
Slide 61
display: none;
visibility: hidden;
opacity: 0;
position: absolute; top: -9999px; left: -9999px;
Visually hidden?
✅
✅
✅
✅
Box model generated?
❌
✅
✅
✅
Affects layout?
❌
✅
✅
❌
Read by assistive technologies?
❌
❌
✅
✅
Slide 62
display: none;
visibility: hidden;
opacity: 0;
position: absolute; top: -9999px; left: -9999px;
Visually hidden?
✅
✅
✅
✅
Box model generated?
❌
✅
✅
✅
Affects layout?
❌
✅
✅
❌
Read by assistive technologies?
❌
❌
✅
✅
Slide 63
display: none;
visibility: hidden;
opacity: 0;
position: absolute; top: -9999px; left: -9999px;
Visually hidden?
✅
✅
✅
✅
Box model generated?
❌
✅
✅
✅
Affects layout?
❌
✅
✅
❌
Read by assistive technologies?
❌
❌
✅
✅
Slide 64
https://frend.co/components/tabs/
Slide 65
display: none;
visibility: hidden;
opacity: 0;
position: absolute; top: -9999px; left: -9999px;
Visually hidden?
✅
✅
✅
✅
Box model generated?
❌
✅
✅
✅
Affects layout?
❌
✅
✅
❌
Read by assistive technologies?
❌
❌
✅
✅
Slide 66
display: none;
visibility: hidden;
opacity: 0;
position: absolute; top: -9999px; left: -9999px;
Visually hidden?
✅
✅
✅
✅
Box model generated?
❌
✅
✅
✅
Affects layout?
❌
✅
✅
❌
Read by assistive technologies?
❌
❌
✅
✅
Slide 67
<div>Element #1</div>
<div style=“visibility:hidden;”> Element #2 </div>
<div>Element #3</div>
Slide 68
Don’t use visibility: hidden;
Slide 69
display: none;
visibility: hidden;
opacity: 0;
position: absolute; top: -9999px; left: -9999px;
Visually hidden?
✅
✅
✅
✅
Box model generated?
❌
✅
✅
✅
Affects layout?
❌
✅
✅
❌
Read by assistive technologies?
❌
❌
✅
✅
Slide 70
display: none;
visibility: hidden;
opacity: 0;
position: absolute; top: -9999px; left: -9999px;
Visually hidden?
✅
✅
✅
✅
Box model generated?
❌
✅
✅
✅
Affects layout?
❌
✅
✅
❌
Read by assistive technologies?
❌
❌
✅
✅
Slide 71
Slide 72
Source order
Visual order
<body> body { display: flex } <footer>…</footer> header { order: 1 } <nav>…</nav> nav { order: 2 } <header>…</header> main { order: 3 } <main>…</main> footer { order: 4 } </body>
Slide 73
“With this power comes great responsibility”
— Rachel Andrew https://rachelandrew.co.uk/archives/2015/07/28/modern-css-layout-power-and-responsibility/
Slide 74
#3
Don’t write CSS that undoes the default accessible styles
Slide 75
Slide 76
✅ Text & element sizes ✅ Colours & contrast ✅ Hover, focus, & active states
Slide 77
Slide 78
button { font-size: 6px; }
Slide 79
button { color: lightgray; }
Slide 80
https://uxplanet.org/active-hover-and-focus-states-for-designers-d789531fe767
Slide 81
https://bitsofco.de/when-do-the-hover-focus-and-active-pseudo-classes-apply/
Slide 82
:active then :focus then :hover ❌
:hover then :focus then :active ✅
button:active { background-color: green; }
button:hover { background-color: red; }
button:focus { background-color: blue; }
button:focus { background-color: blue; }
button:hover { background-color: red; }
button:active { background-color: green; }
Slide 83
Slide 84
❌
✅
:focus { :focus { outline: none; outline: none; other focus styles }
/
*
*
/
}
Slide 85
button:focus:not(:focus-visible) { outline: none; }
button:focus-visible { background-color: darksalmon; }
Slide 86
Write custom CSS cautiously
Slide 87
Slide 88
#4
Do use CSS to improve on the default accessible styles
Slide 89
Guideline 1.4.8 — Visual presentation
- Text blocks should be no wider than 80 characters, for maximum readability. 2. Line height should be at least 1.5 times the text size within paragraphs, and at least 2.25 times the text size between paragraphs.
Slide 90
The default browser styling doesn’t meet these requirements
Slide 91
p { line-height: 1.5; padding: 2.25rem; max-width: 80ch; }
Slide 92
Guideline 2.4.1 — Bypass blocks
A mechanism should be provided that allows the user to skip straight to the main content or functionality available on the page, past the repeated features (such as the company logo or navigation).
Slide 93
<body> #skip-link { <a id=”skip-link” href=”#main”> position: absolute; Skip to content transform: translateY(-100%); </a> }
<!— navigation, etc. #skip-link:focus { transform: translateY(0%); <main id=“main”> }
>
-
</body>
Slide 94
Guideline 2.4.1 — Bypass blocks A mechanism should be provided that allows the user to skip straight to the main content or functionality available on the page, past the repeated features (such as the company logo or navigation). … If a proper structure of headings and semantic containers is provided to navigate with (for example <section>, <aside>, etc.), then an added “skip link” is not needed.
Slide 95
#5
Do adapt CSS to device capabilities
Slide 96
Slide 97
.element { -webkit-transition: all 4s ease; -moz-transition: all 4s ease; -ms-transition: all 4s ease; -o-transition: all 4s ease; transition: all 4s ease; }
Slide 98
.element { color: #000; color: var(—text-color); }
Slide 99
@supports ( declaration ) { Feature-based CSS here
/
*
*
/
}
Slide 100
Legacy code
Modern code @supports (display: grid) {
main {
main {
display: table;
display: grid;
}
} }
Slide 101
#6
Do adapt CSS to user preferences
Slide 102
https://dbaron.org/css/user/
Slide 103
https://codereview.chromium.org/64843004
Slide 104
“All users, including users with disabilities, [should] have equal control over the environment they use to access the web” https://www.w3.org/TR/UAAG20
Slide 105
@media ( prefers-* ) { Preference-based CSS here
/
*
*
/
}
Slide 106
Adapt to data preferences
.element { background-image: url(“highest-quality.png”); }
@media ( prefers-reduced-data: reduce ) { .element { background-image: url(“smaller-size.jpg”); } }
Slide 107
Adapt to data preferences
prefers-reduced-data
Adapt to motion preferences
prefers-reduced-motion
Adapt to colour preferences
prefers-color-scheme
Adapt to contrast preferences
prefers-contrast
Adapt to trasparency preferences
prefers-reduced-transparency
Slide 108
Slide 109
CSS & Accessibility 1. Don’t use CSS to convey meaning or content
- Do use CSS to improve on the default accessible styles
- Don’t use CSS to change the semantics of HTML 3. Don’t write CSS that undoes the default accessible styles
- Do adapt CSS to device capabilities 3. Do adapt CSS to user preferences
Slide 110
Part Two
JavaScript & Accessibility
Slide 111
JavaScript is used to make web pages more interactive
Slide 112
<a>
<details> <form> <summary>
<input>
<button> <select> <textarea>
<option> <progress>
Slide 113
Slide 114
#1
Don’t use JavaScript for functionality HTML provides
Slide 115
✅ Triggered by mouse, enter key, and space bar ✅ Focusable via the keyboard and other input devices ✅ Accessible name and state provided to assistive tech
Slide 116
<button>Do something</button>
Slide 117
<div onClick=“doSomething(e)”> Do something </div>
Slide 118
Extra work 😓 <div tabindex=“0” role=“button” onKeyPress=“handleBtnKeyPress(e)” onClick=“doSomething(e)”> Do something </div>
Slide 119
More extra work 😰 <div tabindex=“0”
function handleBtnKeyPress(e) {
role=“button”
if ( e.keyCode
32 ||
e.keyCode
13) {
onKeyPress=“handleBtnKeyPress(e)” onClick=“doSomething(e)”>
doSomething(e);
Do something
}
</div>
=
=
=
=
=
=
}
Slide 120
Even more extra work 🥵 <div tabindex=“0” role=“button” onKeyPress=“handleBtnKeyPress(e)” onClick=“doSomething(e)” aria-pressed=”false”> Toggle </div>
Slide 121
Slide 122
✅
❌
<button onClick=“goToPage(‘/about’)”> <a href=“/about”>About Us</a>
About Us </button>
Slide 123
<button onClick=“goToPage(‘/about’)”> About Us </button>
function goToPage(url) { // Do some other things window.location.href = url; }
Slide 124
Keep JavaScript enhancements unobtrusive
Slide 125
<a href=“/about” onClick=“goToPage(event, ’/about’)”> About Us </a>
function goToPage(event, url) { event.preventDefault(); // Do some other things window.location.href = url; }
Slide 126
<a href=“/about” onClick=“goToPage(e, ’/about’)”> About Us </a>
function goToPage(e, url) { e.preventDefault(); // Do some other things window.location.href = url; }
Slide 127
event.preventDefault() is the 🔑
Slide 128
#2
Where possible, don’t require JavaScript for critical features
Slide 129
Slide 130
Slide 131
“While WCAG 1.0 from 1999 required that pages be functional and accessible with scripting disabled, WCAG 2 and all other modern guidelines allow you to require JavaScript” https://webaim.org/techniques/javascript/
Slide 132
Different groups have different access needs
Slide 133
People with physical disabilities are more likely to rely on JS Only 0.07% of screen reader users have JavaScript disabled. The global average is 1%.
Slide 134
People with socio-economic restrictions are more likely to avoid JS Over 50% of the Sudanese mobile browsing is with Opera Mini
Slide 135
Average File Sizes 430 KB
27 KB HTML
66 KB CSS
https://almanac.httparchive.org/en/2021/page-weight
JS
Slide 136
Slide 137
JavaScript-disabled experience
JavaScript-enabled experience
Slide 138
JavaScript-enabled experience JavaScript-disabled experience
Slide 139
JavaScript-disabled experience
JavaScript-enabled experience
Slide 140
“Just because JavaScript is used on a page does not mean that the page is inaccessible. In many cases, JavaScript can be used to greatly improve accessibility and optimize the user experience.” https://webaim.org/techniques/javascript/
Slide 141
“Just because JavaScript is used on a page does not mean that the page is inaccessible. In many cases, JavaScript can be used to greatly improve accessibility and optimize the user experience.” https://webaim.org/techniques/javascript/
Slide 142
#3
Do use JavaScript to improve on the default accessible behaviour
Slide 143
Slide 144
Guideline 3.3.3 — When an error is detected and suggestions for correction are known, provide these to the user
Slide 145
Slide 146
Some HTML elements aren’t accessible enough, yet ☹
Slide 147
Problems with <video> ❌ Controls not focusable via keyboard ❌ Can’t pause/play video using space key ❌ No arrow key support for scrubber & more
Slide 148
“Modern browsers provide a default media player. Most have limited functionality to support accessibility.” https://www.w3.org/WAI/media/av/player/
Slide 149
https://www.digitala11y.com/accessible-jquery-html5-media-players/
Slide 150
Problems with <canvas> ❌ Content not in the DOM & AOM ❌ No “proper” text alternatives ❌ “Elements” not focusable & more
Slide 151
Sometimes, we need JavaScript
Slide 152
#4
Do use JavaScript to create components that don’t exist
Slide 153
Slide 154
<tooltip>
<dropdown>
<carousel> <tab-group> <toggle> <card> <social-button>
<accordion> <loading>
<tab>
Slide 155
https://www.w3.org/TR/2021/NOTE-wai-aria-practices-1.2-20211129/examples/carousel/carousel-1-prev-next.html
Slide 156
Guidelines related to carousels 1.3.1 — Information, structure, and relationships conveyed through presentation can be programmatically determined 2.1.1 — All functionality should be accessible using keyboard controls 2.2.2 — Controls should be provided to pause, stop, or hide moving content 4.1.2 — The name and role of user interface components (e.g. form inputs, buttons, links, etc.) should be programmatically determinable
Slide 157
<ul id=”slides”> <li>
Slide One
</li>
<li>
Slide Two
</li>
<li>
Slide Three
/
*
/
/
*
*
*
*
*
/
/
/
</ul>
</li>
Slide 158
<section> <div> <button>Toggle Play Slideshow</button> <button>Previous Slide</button> <button>Next Slide</button> </div> <ul id=”slides”> <li> … </li> </ul> </section>
Slide 159
<section> <div> <button>Toggle Play Slideshow</button> <button>Previous Slide</button> <button>Next Slide</button> </div> <ul id=”slides”> <li> … </li> </ul> </section>
Slide 160
<section> <div> <button>Toggle Play Slideshow</button> <button>Previous Slide</button> <button>Next Slide</button> </div> <ul id=”slides”> <li> … </li> </ul> </section>
Slide 161
<section aria-roledescription=”carousel” aria-label=“Slideshow”> <div> <button>Toggle Play Slideshow</button> <button aria-controls=”slides”>Previous Slide</button> <button aria-controls=”slides”>Next Slide</button> </div> <ul id=”slides”> <li role=”group” aria-roledescription=”slide” aria-label=”1 of 3”> … </li> </ul> </section>
Slide 162
Write custom components cautiously
Slide 163
https://www.w3.org/TR/2021/NOTE-wai-aria-practices-1.2-20211129/examples/
Slide 164
Slide 165
https://inclusive-components.design/
Slide 166
JavaScript & Accessibility 1. Don’t use JavaScript for functionality HTML provides 2. Where possible, don’t require JavaScript for critical features
- Do use JavaScript to improve on the default accessible behaviour 2. Do use JavaScript to create components that don’t exist
Slide 167
“By default, HTML is accessible, if used correctly. Web accessibility involves ensuring that content remains accessible.” https://developer.mozilla.org/en-US/docs/Learn/Accessibility
Slide 168
“So next time someone tells you to make things accessible, tell them that instead you don’t intend to make it inaccessible in the rst place.”
— George Kemp
fi
https://dev.to/gkemp94/the-web-is-accessible-by-default-stop-breaking-it-4cg4
Slide 169
Thank you! Ire Aderinokun 🇳🇬 COO & VP Engineering of Helicarrier Google Web Expert
ireaderinokun.com bitsofco.de @ireaderinokun