It’s the markup that matters

A presentation at CodeLand 2021 in September 2021 in by Hidde de Vries

Slide 1

Slide 1

It’s the markup Hidde de Vries / CodeLand 2021 that matters

Slide 2

Slide 2

hidde.blog @hdv @hdv

Slide 3

Slide 3

security performance Quality of websites accessibility @hdv @hdv usability

Slide 4

Slide 4

Accessible to People with permanent disabilities @hdv @hdv People with temporary disabilities People in certain situations

Slide 5

Slide 5

Responsibility of Content designers Web developers UI designers CMS integrators User researchers @hdv @hdv

Slide 6

Slide 6

Responsibility of Content designers Web developers UI designers CMS integrators @hdv @hdv User researchers

Slide 7

Slide 7

Code Assistive Technologies (AT) text-to-speec screen magni er alternate pointing devices s fi h @hdv

Slide 8

Slide 8

@hdv @hdv

Slide 9

Slide 9

@hdv @hdv

Slide 10

Slide 10

@hdv @hdv

Slide 11

Slide 11

@hdv @hdv

Slide 12

Slide 12

@hdv @hdv

Slide 13

Slide 13

Example of an Accessibility Tree・ https://github.com/WICG/aom/blob/gh-pages/images/a11y-node.png

Slide 14

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

Slide 15

Accessible code points machines at what stuff is @hdv @hdv

Slide 16

Slide 16

Accessible code points machines at what stuff is called @hdv @hdv

Slide 17

Slide 17

Accessible code points machines in what state stuff is @hdv @hdv

Slide 18

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 19

@hdv

Slide 20

Slide 20

It’s the markup that matters @hdv

Slide 21

Slide 21

What’s this page? @hdv

Slide 22

Slide 22

<html lang=”nl”> <head> <title>It’s the markup that matters Presentations - My site</title> </head> <body> … </body> </html> @hdv

Slide 23

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

Slide 24

What’s on this page? Headings @hdv

Slide 25

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 26

@hdv

Slide 27

Slide 27

What’s on this page? Landmarks @hdv

Slide 28

Slide 28

Landmarks let you specify which sections a page has, so that people can navigate to them @hdv

Slide 29

Slide 29

@hdv HTML5 ARIA roles

<header> <footer> <nav> <aside> <main> role=”banner” role=”contentinfo” role=”navigation” role=”complementary” role=”main”

Slide 30

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

Slide 31

HTML5 <header> <footer> <nav> <aside> <main> @hdv

Slide 32

Slide 32

Form controls @hdv

Slide 33

Slide 33

“ “59% of form inputs were not properly labeled.”. — WebAIM The WebAIM Million ・ https://webaim.org/projects/million/

Slide 34

Slide 34

Label input elds, radio buttons, checkboxes, selects, textareas, etc… so that they have a name fi @hdv

Slide 35

Slide 35

First Name

<div class=”form-item”> First Name <input type=”text” /> </div> @hdv Role: ‘textbox’ / ‘entry’ Name: null / ”

Slide 36

Slide 36

Accessible Name and Description Computation 1.1 ・ https://www.w3.org/TR/accname-1.1/

Slide 37

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 38

Table semantics @hdv

Slide 39

Slide 39

Tables make tabular data easier to navigate @hdv

Slide 40

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 41

Slide 42

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 43

Language @hdv

Slide 44

Slide 44

The lang attribute lets you specify which language content is in @hdv

Slide 45

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

Slide 46

If buttons are just icons @hdv

Slide 47

Slide 47

The “Add Reaction” button

Slide 48

Slide 48

<div class=”icon” onclick=”emoji()”> <svg class=”icon”> <use xlink:href=”#emoji”></use> </svg> </div> Role: ” Name: ”

Slide 49

Slide 49

// use the button element <button type=”button”> <svg class=”icon”> <use xlink:href=”#emoji”></use> </svg> </button> Role: ‘button’ Name: ”

Slide 50

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

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

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

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

Slide 54

No meaningful mark-up for your component? ARIA can poly ll! fi @hdv

Slide 55

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

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

Slide 57

Not all ARIA has good support or provides good usability for AT users. @hdv

Slide 58

Slide 58

Expandables @hdv

Slide 59

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

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

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 62

Announcements @hdv

Slide 63

Slide 63

Your changes were saved successfully! @hdv

Slide 64

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

Slide 65

Meaning without mark-up: the Accessibility Object Model @hdv

Slide 66

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

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

Slide 68

<my-custom-element role=”button” aria-disabled=”false” … /> No more “sprouting” @hdv

Slide 69

Slide 69

const el = document.querySelector(“el”); el.role = “button”; el.ariaDisabled = false; Set ARIA with IDL attributes instead of markup @hdv

Slide 70

Slide 70

Relationships without IDREFs @hdv

Slide 71

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

Slide 72

Events from Assistive Technologies @hdv

Slide 73

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

Slide 74

Reading accessibility tree through JavaScript @hdv

Slide 75

Slide 75

TLDR

Slide 76

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