Slide 1
It’s the markup Hidde de Vries / CodeLand 2021
that matters
Slide 2
Slide 3
security
performance
Quality of websites accessibility @hdv @hdv
usability
Slide 4
Accessible to People with permanent disabilities
@hdv @hdv
People with temporary disabilities
People in certain situations
Slide 5
Responsibility of Content designers Web developers UI designers CMS integrators User researchers @hdv @hdv
Slide 6
Responsibility of Content designers
Web developers UI designers CMS integrators @hdv @hdv
User researchers
Slide 7
Code
Assistive Technologies (AT)
text-to-speec screen magni er alternate pointing devices
s
fi
h
@hdv
Slide 8
Slide 9
Slide 10
Slide 11
Slide 12
Slide 13
Example of an Accessibility Tree・ https://github.com/WICG/aom/blob/gh-pages/images/a11y-node.png
Slide 14
Role What kind of thing is it? Name/Description How should we refer to it? State/properties What else should we know? @hdv
Slide 15
Accessible code points machines at what stuff is
@hdv @hdv
Slide 16
Accessible code points machines at what stuff is called
@hdv @hdv
Slide 17
Accessible code points machines in what state stuff is
@hdv @hdv
Slide 18
Accessibility tree
Platform APIs
AT
Your markup
DOM tree
Microsoft Active Accessibility Microsoft User Interface Automation MSAA
Mac OS X Accessibility Protocol
text-to-speech Linux/Unix Accessibility Toolkit IAccessible2
fi
@hdv
screen magni ers alternate pointing devices
Slide 19
Slide 20
It’s the markup that matters
@hdv
Slide 21
Slide 22
<html lang=”nl”> <head> <title>It’s the markup that matters Presentations - My site</title> </head> <body> … </body> </html> @hdv
Slide 23
— Léonie Watson, accessibility expert and screenreader user
fi
Smashing TV with Léonie Watson・ https://www.youtube.com/watch?v=iUCYPM6up9M. fi
fi
“
[The <title>] is still the rst guarantee or rst con rmation that you’ve ended up on the page that you intended to reach.
Slide 24
What’s on this page? Headings
@hdv
Slide 25
fi
“Navigate by heading” is a very common way for AT users to gure out what’s on a page
Heading structures are tables of contents ・ https://hiddedevries.nl/en/blog/2018-09-01-heading-structures-are-tables-of-contents
Slide 26
Slide 27
What’s on this page? Landmarks
@hdv
Slide 28
Landmarks let you specify which sections a page has, so that people can navigate to them
@hdv
Slide 29
@hdv
HTML5
ARIA roles
<header> <footer> <nav> <aside> <main>
role=”banner” role=”contentinfo” role=”navigation” role=”complementary” role=”main”
Slide 30
“
Built-in beats bolt-on. — Bruce Lawson
Bruce Lawson: AOM-NOM-NOM・ https://noti.st/brucelawson/wLB2lE/aom-nom-nom#sgf2LTe
Slide 31
HTML5 <header> <footer> <nav> <aside> <main>
@hdv
Slide 32
Slide 33
“
“59% of form inputs were not properly labeled.”. — WebAIM
The WebAIM Million ・ https://webaim.org/projects/million/
Slide 34
Label input elds, radio buttons, checkboxes, selects, textareas, etc… so that they have a name
fi
@hdv
Slide 35
First Name
<div class=”form-item”> First Name <input type=”text” /> </div>
@hdv
Role: ‘textbox’ / ‘entry’ Name: null / ”
Slide 36
Accessible Name and Description Computation 1.1 ・ https://www.w3.org/TR/accname-1.1/
Slide 37
First Name
<div class=”form-item”> <label for=”fn”>First Name</label> <input id=”fn” type=”text” /> </div>
@hdv
Role: ‘textbox’ / ‘entry’ Name: ‘First Name’
Slide 38
Slide 39
Tables make tabular data easier to navigate
@hdv
Slide 40
<table> <caption>Net results 2018</caption> <thead> <tr> <th scope=”col”>Assets</th>
Use table semantics
<th scope=”col”>Capital</th> … </tr> </thead> <tbody> … </tbody>
@hdv
</table>
Slide 41
Slide 42
<table> <caption>Net results 2018</caption> <thead> <tr> <th scope=”col”>Assets</th>
Use table semantics
<th scope=”col”>Capital</th> … </tr> </thead> <tbody> … </tbody>
@hdv
</table>
Slide 43
Slide 44
The lang attribute lets you specify which language content is in
@hdv
Slide 45
Specify languages with lang <div> <p lang=”de”>Wilkommen</p> <p lang=”fr”>Bienvenue</p> <p lang=”en”>Welcome</p> </div>
@hdv
Slide 46
If buttons are just icons
@hdv
Slide 47
The “Add Reaction” button
Slide 48
<div class=”icon” onclick=”emoji()”> <svg class=”icon”> <use xlink:href=”#emoji”></use> </svg> </div>
Role: ” Name: ”
Slide 49
// use the button element <button type=”button”> <svg class=”icon”> <use xlink:href=”#emoji”></use> </svg> </button>
Role: ‘button’ Name: ”
Slide 50
<button type=”button”> <svg class=”icon”> <use xlink:href=”#emoji”></use> </svg> // add accessible name <span class=”visually-hidden”> Add reaction </span> </button>
Role: ‘button’ Name: ‘Add reaction’
Slide 51
<button type=”button”> // hide icon from a11y tree <svg class=”icon” role=”presentation”
“Accessibility node not exposed”
aria-hidden=”true” focusable=”false”> <use xlink:href=”#emoji”></use> </svg> <span class=”visually-hidden”>
Slide 52
“
It would appear that either aria-hidden=”true” or role=”presentation” should be able to help out here. — John Foliot
HTML5 Accessibility: aria-hidden and role=”presentation” ・ http://john.foliot.ca/aria-hidden/
Slide 53
<button type=”button”> <svg class=”icon” role=”presentation” aria-hidden=”true” focusable=”false”>
Avoids weird focus bugs in IE11
<use xlink:href=”#emoji”></use> </svg> <span class=”visually-hidden”> Add reaction
Slide 54
No meaningful mark-up for your component? ARIA can poly ll!
fi
@hdv
Slide 55
ARIA can provide names, roles, property and states through attributes.
Accessible Rich Internet Applications (WAI-ARIA) 1.1 ・ https://www.w3.org/TR/wai-aria/
Slide 56
There usually is existing HTML for your problem, combining existing elements FTW!
Web Components as compositions of native elements ・ https://hiddedevries.nl/en/blog/2017-10-19-web-components-as-compositions-of-native-elements
Slide 57
Not all ARIA has good support or provides good usability for AT users.
@hdv
Slide 58
Slide 59
Tooltip <button
Enter your IBAN number ?
type=”button” aria-controls=”tooltip”
An IBAN-number is a 34 characters string, please double check with your bank if you’re not sure what yours is.
What’s IBAN? </button>
<div id=”tooltip”> An IBAN-number is a 34 ch… @hdv
</div>
Slide 60
Tooltip <button
Enter your IBAN number ?
type=”button” aria-controls=”tooltip”
An IBAN-number is a 34 characters string, please double check with your bank if you’re not sure what yours is.
aria-expanded=”true” > What’s IBAN? </button>
<div id=”tooltip”> @hdv
An IBAN-number is a 34 ch…
Slide 61
Tooltip <button
Enter your IBAN number ?
type=”button” aria-controls=”tooltip” aria-expanded=”false” > What’s IBAN? </button>
<div id=”tooltip” hidden> @hdv
An IBAN-number is a 34 ch…
Slide 62
Slide 63
Your changes were saved successfully!
@hdv
Slide 64
<div role=”alert”> </div>
// We’ve just used fetch() to POST form // data on the submit event of a form. // Let’s say we’re handling like:
const el = document.querySelector(“div”);
el.textContent(“Your changes were saved successfully”);
@hdv
Your changes were saved successfully!
Slide 65
Meaning without mark-up: the Accessibility Object Model
@hdv
Slide 66
“
“This effort aims to develop additions to the web platform to allow developers to provide information to assistive technology APIs, and to understand what information browsers provide to those APIs.” — The AOM explainer document
The Accessibility Object Model (AOM) ・ https://github.com/WICG/aom
Slide 67
AOM doesn’t bring new semantics or states, it introduces new ways to specify them
The Accessibility Object Model (AOM) ・ https://github.com/WICG/aom
Slide 68
<my-custom-element role=”button” aria-disabled=”false” … />
No more “sprouting”
@hdv
Slide 69
const el = document.querySelector(“el”);
el.role = “button”; el.ariaDisabled = false;
Set ARIA with IDL attributes instead of markup
@hdv
Slide 70
Relationships without IDREFs
@hdv
Slide 71
aria-activedescendant aria-colcount aria-colindex aria-colspan aria-controls aria-describedby aria-details aria-errormessage @hdv
aria-flowto aria-labelledby aria-owns aria-posinset aria-rowcount aria-rowindex aria-rowspan aria-setsize
Slide 72
Events from Assistive Technologies
@hdv
Slide 73
// Implementing a canvas-based // spreadsheet’s semantics canvas.attachAccessibleRoot();
let table = canvas.accessibleRoot .appendChild(new AccessibleNode());
table.role = “table”; table.colCount = 10; table.rowcount = 100;
Non-DOM nodes in the Accessibility Tree
let headerRow = table.appendChild( appendChild(new AccessibleNode()) ); headerRow.role = “row”; headerRow.rowindex = 0; Example from: AOM explainer
・ https://wicg.github.io/aom/explainer.html#the-accessibility-object-model
Slide 74
Reading accessibility tree through JavaScript
@hdv
Slide 75
Slide 76
Our apps need to be accessible Good mark-up makes a difference, it gives us lots of accessibility for free Always consider which names, roles and states your markup conveys @hdv