A presentation at An Event Apart Spring Summit by Ire Aderinokun
CSS, JavaScript, & Accessibility Ire Aderinokun @ An Event Apart Spring Summit 2022
“By default, HTML is accessible. Web accessibility involves ensuring that content remains accessible.” https://developer.mozilla.org/en-US/docs/Learn/Accessibility
Web accessibility is the inclusive practice of ensuring there are no barriers that prevent access to websites
Physical disabilities
Situational disabilities
Socio-economic restrictions
Accessibility is about inclusion
“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
With HTML, WYSIWYG
In the absence of other languages, we have to use HTML correctly
https://ireade.github.io/motherduckingwebsite/
https://ireade.github.io/motherduckingwebsite/
By default, HTML is perceivable 🧏
Guideline 1.3 — Create content that can be presented in different ways ✅
Guideline 1.4 — Make it easier for users to see and hear content including separating foreground from background ✅
By default, HTML is operable 🛠
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 ✅
By default, HTML is understandable 📖
Guideline 3.2 — Make Web pages appear and operate in predictable ways ✅
Guideline 3.3 — Help users avoid and correct mistakes ✅
By default, HTML is robust ⚙
By default, HTML is robust, if used correctly ✅
HTML can be inaccessible
Missing text alternatives ☹ <img src=“link/to/really-important-image.png”
Using the wrong elements ☹
<p>Enter your username:</p> <input type=“text”>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>HTML
JavaScript CSS
Adding content with CSS ☹
<div id=“important”></div> #important after { content: “Really important information that everyone should know” : : }Altering element behaviour with JavaScript ☹
<div onClick=“goToPage(‘/about’)”> About Us </div>90% of accessibility is about using HTML correctly. The other 10% is about not using CSS/JS incorrectly.
CSS, JavaScript, & Accessibility
Part One CSS & Accessibility
CSS is used to describe the presentation of an HTML document
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>
CSSOM body { font-size: 18px; } header { color: plum; } h1 { font-size: 28px; } main { color: firebrick; } h2 { font-size: 20px; } footer { display: none; }
DOM + CSSOM - Non-visible elements = Render tree
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>
#1 Don’t use CSS to convey meaning or content
h1 after { content: “My Page Title” : : }
https://tink.uk/accessibility-support-for-css-generated-content/
“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/
❌ ✅ .element after { content: .element any content content: “” / * * / : : : } : } after {
<input class=“error” > <input class=“success” > .error { border-color: red; } .success { border-color: green; }
#2 Don’t use CSS to change the semantics of HTML
❌ ✅ This is <span class=“emphasise”>really</span> important .emphasise { font-style: italic; } This is <em>really</em> important
display: none; visibility: hidden; opacity: 0; position: absolute; top: -9999px; left: -9999px; Visually hidden? ✅ ✅ ✅ ✅ Box model generated? ❌ ✅ ✅ ✅ Affects layout? ❌ ✅ ✅ ❌ Read by assistive technologies? ❌ ❌ ✅ ✅
display: none; visibility: hidden; opacity: 0; position: absolute; top: -9999px; left: -9999px; Visually hidden? ✅ ✅ ✅ ✅ Box model generated? ❌ ✅ ✅ ✅ Affects layout? ❌ ✅ ✅ ❌ Read by assistive technologies? ❌ ❌ ✅ ✅
display: none; visibility: hidden; opacity: 0; position: absolute; top: -9999px; left: -9999px; Visually hidden? ✅ ✅ ✅ ✅ Box model generated? ❌ ✅ ✅ ✅ Affects layout? ❌ ✅ ✅ ❌ Read by assistive technologies? ❌ ❌ ✅ ✅
https://frend.co/components/tabs/
display: none; visibility: hidden; opacity: 0; position: absolute; top: -9999px; left: -9999px; Visually hidden? ✅ ✅ ✅ ✅ Box model generated? ❌ ✅ ✅ ✅ Affects layout? ❌ ✅ ✅ ❌ Read by assistive technologies? ❌ ❌ ✅ ✅
display: none; visibility: hidden; opacity: 0; position: absolute; top: -9999px; left: -9999px; Visually hidden? ✅ ✅ ✅ ✅ Box model generated? ❌ ✅ ✅ ✅ Affects layout? ❌ ✅ ✅ ❌ Read by assistive technologies? ❌ ❌ ✅ ✅
Don’t use visibility: hidden;
display: none; visibility: hidden; opacity: 0; position: absolute; top: -9999px; left: -9999px; Visually hidden? ✅ ✅ ✅ ✅ Box model generated? ❌ ✅ ✅ ✅ Affects layout? ❌ ✅ ✅ ❌ Read by assistive technologies? ❌ ❌ ✅ ✅
display: none; visibility: hidden; opacity: 0; position: absolute; top: -9999px; left: -9999px; Visually hidden? ✅ ✅ ✅ ✅ Box model generated? ❌ ✅ ✅ ✅ Affects layout? ❌ ✅ ✅ ❌ Read by assistive technologies? ❌ ❌ ✅ ✅
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>“With this power comes great responsibility” — Rachel Andrew https://rachelandrew.co.uk/archives/2015/07/28/modern-css-layout-power-and-responsibility/
#3 Don’t write CSS that undoes the default accessible styles
Browser CSS
✅ Text & element sizes ✅ Colours & contrast ✅ Hover, focus, & active states
My CSS Browser CSS
button { font-size: 6px; }
button { color: lightgray; }
https://uxplanet.org/active-hover-and-focus-states-for-designers-d789531fe767
https://bitsofco.de/when-do-the-hover-focus-and-active-pseudo-classes-apply/
: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; }
❌ ✅ :focus { :focus { outline: none; outline: none; other focus styles } / * * / }
button:focus:not(:focus-visible) { outline: none; } button:focus-visible { background-color: darksalmon; }
Write custom CSS cautiously
#4 Do use CSS to improve on the default accessible styles
Guideline 1.4.8 — Visual presentation
The default browser styling doesn’t meet these requirements
p { line-height: 1.5; padding: 2.25rem; max-width: 80ch; }
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).
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.
#5 Do adapt CSS to device capabilities
CSS
.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; }
.element { color: #000; color: var(—text-color); }
@supports ( declaration ) { Feature-based CSS here / * * / }
Legacy code Modern code @supports (display: grid) { main { main { display: table; display: grid; } } }
#6 Do adapt CSS to user preferences
https://dbaron.org/css/user/
https://codereview.chromium.org/64843004
“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
@media ( prefers-* ) { Preference-based CSS here / * * / }
Adapt to data preferences .element { background-image: url(“highest-quality.png”); } @media ( prefers-reduced-data: reduce ) { .element { background-image: url(“smaller-size.jpg”); } }
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
Giving users control
CSS & Accessibility 1. Don’t use CSS to convey meaning or content
Part Two JavaScript & Accessibility
JavaScript is used to make web pages more interactive
#1 Don’t use JavaScript for functionality HTML provides
✅ Triggered by mouse, enter key, and space bar ✅ Focusable via the keyboard and other input devices ✅ Accessible name and state provided to assistive tech
<button>Do something</button>
Extra work 😓 <div tabindex=“0” role=“button” onKeyPress=“handleBtnKeyPress(e)” onClick=“doSomething(e)”> Do something </div>
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> = = = = = = }Even more extra work 🥵 <div tabindex=“0” role=“button” onKeyPress=“handleBtnKeyPress(e)” onClick=“doSomething(e)” aria-pressed=”false”> Toggle </div>
✅ ❌ <button onClick=“goToPage(‘/about’)”> <a href=“/about”>About Us</a> About Us </button>
<button onClick=“goToPage(‘/about’)”> About Us </button> function goToPage(url) { // Do some other things window.location.href = url; }
Keep JavaScript enhancements unobtrusive
<a href=“/about” onClick=“goToPage(event, ’/about’)”> About Us </a> function goToPage(event, url) { event.preventDefault(); // Do some other things window.location.href = url; }
<a href=“/about” onClick=“goToPage(e, ’/about’)”> About Us </a> function goToPage(e, url) { e.preventDefault(); // Do some other things window.location.href = url; }
event.preventDefault() is the 🔑
#2 Where possible, don’t require JavaScript for critical features
Without JS With JS
“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/
Different groups have different access needs
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%.
People with socio-economic restrictions are more likely to avoid JS Over 50% of the Sudanese mobile browsing is with Opera Mini
Average File Sizes 430 KB 27 KB HTML 66 KB CSS https://almanac.httparchive.org/en/2021/page-weight JS
JavaScript-disabled experience JavaScript-enabled experience
JavaScript-enabled experience JavaScript-disabled experience
JavaScript-disabled experience JavaScript-enabled experience
“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/
“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/
#3 Do use JavaScript to improve on the default accessible behaviour
Guideline 3.3.3 — When an error is detected and suggestions for correction are known, provide these to the user
Some HTML elements aren’t accessible enough, yet ☹
Problems with <video> ❌ Controls not focusable via keyboard ❌ Can’t pause/play video using space key ❌ No arrow key support for scrubber & more
“Modern browsers provide a default media player. Most have limited functionality to support accessibility.” https://www.w3.org/WAI/media/av/player/
https://www.digitala11y.com/accessible-jquery-html5-media-players/
Problems with <canvas> ❌ Content not in the DOM & AOM ❌ No “proper” text alternatives ❌ “Elements” not focusable & more
Sometimes, we need JavaScript
#4 Do use JavaScript to create components that don’t exist
https://www.w3.org/TR/2021/NOTE-wai-aria-practices-1.2-20211129/examples/carousel/carousel-1-prev-next.html
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
Write custom components cautiously
https://www.w3.org/TR/2021/NOTE-wai-aria-practices-1.2-20211129/examples/
https://frend.co/
https://inclusive-components.design/
JavaScript & Accessibility 1. Don’t use JavaScript for functionality HTML provides 2. Where possible, don’t require JavaScript for critical features
“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
“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
Thank you! Ire Aderinokun 🇳🇬 COO & VP Engineering of Helicarrier Google Web Expert ireaderinokun.com bitsofco.de @ireaderinokun
HTML is, by default, accessible. By simply using “Plain Old Semantic HTML”, we have the ability to create rich and accessible web pages that can meaningfully stand on their own. More often than not, what makes a web page less accessible is the CSS and JavaScript we add to that HTML. With these additions, we can alter the meaning of elements, change their behaviour, or even block access to content entirely.
In this talk, we’ll explore how CSS and JavaScript can contribute, negatively or positively, to accessibility. We’ll learn when it’s appropriate to use these technologies and how they can be used to make even more accessible websites - from leveraging CSS to adapt experiences to different types of users, to using JavaScript to ensure our dynamic web applications work across all devices.