Writing even more CSS with Accessibility in mind

A presentation at Inclusive Design 24 in September 2020 in by Manuel Matuzovic

Slide 1

Slide 1

H IT W S S C E R O M N E V E G WRITIN D IN M IN Y IT IL ACCESSIB #ID24 September 17th, 2020 matuzo.at @mmatuzo

Slide 2

Slide 2

Manuel Matuzovic HTML · CSS · a11y · performance City of Vienna · WACA webclerks · HTMHell · Frontend-Bookmarks manuel@matuzo.at · @mmatuzo @mmatuzo

Slide 3

Slide 3

@mmatuzo

Slide 4

Slide 4

Writing even more CSS with accessibility in mind • Progressive Enhancement • Respecting User Preferences • Improving Accessibility with CSS • CSS and Semantics @mmatuzo

Slide 5

Slide 5

Progressive Enhancement @mmatuzo

Slide 6

Slide 6

Progressive Enhancement @mmatuzo

Slide 7

Slide 7

Progressive Enhancement @mmatuzo

Slide 8

Slide 8

progressive enhancement HTML: Foundation / Semantic markup CSS: Design and visual improvements JS: Enhanced experience @mmatuzo

Slide 9

Slide 9

progressive enhancement div { color: #FFFFFF; css-is: amazing; CSS <3 background: #000000; } @mmatuzo

Slide 10

Slide 10

progressive enhancement @mmatuzo

Slide 11

Slide 11

progressive enhancement img { float: left; shape-outside: polygon(0.23% 2px, 17.11% 0.84%, 61.14% 21.01%, 69.91% 20.17%, 86.88% 27.73%, 90.64% 36.09%, 86.53% 50.56%, 80.07% 79.29%, 86.55% 99.48%, 0px 100%); shape-margin: 20px; } @mmatuzo

Slide 12

Slide 12

progressive enhancement img { float: left; shape-outside: polygon(0.23% 2px, 17.11% 0.84%, 61.14% 21.01%, 69.91% 20.17%, 86.88% 27.73%, 90.64% 36.09%, 86.53% 50.56%, 80.07% 79.29%, 86.55% 99.48%, 0px 100%); shape-margin: 20px; } @mmatuzo

Slide 13

Slide 13

progressive enhancement @mmatuzo

Slide 14

Slide 14

progressive enhancement <head> <script type=”module”> “// Add the .js class to the <html> element document.documentElement.classList.add(‘js’) “</script> “</head> @mmatuzo

Slide 15

Slide 15

@mmatuzo

Slide 16

Slide 16

progressive enhancement @mmatuzo

Slide 17

Slide 17

progressive enhancement .js .accordion”__panel { display: none; } @mmatuzo

Slide 18

Slide 18

progressive enhancement @mmatuzo

Slide 19

Slide 19

@mmatuzo

Slide 20

Slide 20

Respecting User Preferences @mmatuzo

Slide 21

Slide 21

Font Size @mmatuzo

Slide 22

Slide 22

font size @mmatuzo

Slide 23

Slide 23

font size body { “/* Don’t use px for font sizes “*/ font-size: 18px; } @mmatuzo

Slide 24

Slide 24

font size target font size base font size 18px 16px rem size 1.125rem @mmatuzo

Slide 25

Slide 25

font size body { font-size: 1.125rem; “/* 16 * 1.125 = 18px “*/ } @mmatuzo

Slide 26

Slide 26

Motion and Animation @mmatuzo

Slide 27

Slide 27

motion and animation @mmatuzo

Slide 28

Slide 28

Really, there are no words to describe just how bad a simple parallax effect, scrolljacking, or even background-attachment: fixed would make me feel. I would rather jump on one of those 20-G centrifuges astronauts use than look at a website with parallax scrolling. Facundo Corradini @mmatuzo

Slide 29

Slide 29

The extreme, conscious, focused effort it took to read would make it such that anything moving on the screen would instantly break my focus, and force me to start the paragraph all over. And I mean anything. Facundo Corradini @mmatuzo

Slide 30

Slide 30

motion and animation @keyframes walk { 0% { transform: translateX(100vw); } } img { animation: walk 10s linear infinite; } @media (prefers-reduced-motion: reduce) { img { animation: none; } } @mmatuzo

Slide 31

Slide 31

motion and animation <picture> <source srcset=”moonwalk.jpg” media=”(prefers-reduced-motion: reduce)” “/> <img src=”moonwalk.gif” alt=”Someone doing the moonwalk” “/> “</picture> @mmatuzo

Slide 32

Slide 32

@mmatuzo

Slide 33

Slide 33

motion and animation img { animation: walk 10s linear infinite; } div { transition: transform 1s ease-in; } “/* has no effect in browsers that don’t support prefers-reduced-motion “*/ @media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } } @mmatuzo

Slide 34

Slide 34

@mmatuzo

Slide 35

Slide 35

motion and animation “/* has no effect in browsers that don’t support prefers-reduced-motion “*/ @media (prefers-reduced-motion: no-preference) { img { animation: walk 10s linear infinite; } div { transition: transform 1s ease-in; } } @mmatuzo

Slide 36

Slide 36

motion and animation @media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } } @mmatuzo

Slide 37

Slide 37

Improving .a y with CSS @mmatuzo

Slide 38

Slide 38

Explaining user interfaces @mmatuzo

Slide 39

Slide 39

Explaining user interfaces <a href=”menu.html”> Our Menu Our Menu “</a> <a href=”menu.pdf” download> Our Menu Our Menu “</a> @mmatuzo

Slide 40

Slide 40

Explaining user interfaces [attribute] { } a[download]”::after { background-image: url(‘icons/download.svg’); content: “”; display: inline-block; background-size: contain; } @mmatuzo

Slide 41

Slide 41

Explaining user interfaces <a href=”menu.html”> Our Menu Our Menu “</a> <a href=”menu.pdf” download> Our Menu Our Menu “</a> @mmatuzo

Slide 42

Slide 42

Explaining user interfaces @mmatuzo

Slide 43

Slide 43

Explaining user interfaces <!— screen reader sprite sheet —> <div hidden> <span id=”new-window-0”>Opens in a new window”</span> <span id=”new-window-1”>Opens an external site”</span> <span id=”new-window-2”>File download”</span> “</div> @mmatuzo

Slide 44

Slide 44

Explaining user interfaces <a href=”https:”//css-irl.info/”> Michelle Barker’s website “</a> “Michelle Barker’s website, link” @mmatuzo

Slide 45

Slide 45

Explaining user interfaces <a href=”https:”//css-irl.info/”> Michelle Barker’s website “</a> “Michelle Barker’s website, link” <a href=”https:”//css-irl.info/” aria-describedby=”new-window-1”> Michelle Barker’s website “</a> “Michelle Barker’s website, Opens an external site, link” @mmatuzo

Slide 46

Slide 46

Explaining user interfaces [aria-describedby=”new-window-1”] { background-image: url(‘icons/external.svg’); … } a[href”^=”http:”//”], a[href”^=”https:”//”] { background-image: url(‘icons/external.svg’); … } @mmatuzo

Slide 47

Slide 47

Testing accessibility @mmatuzo

Slide 48

Slide 48

Testing accessibility @mmatuzo

Slide 49

Slide 49

Testing accessibility “/* Force yourself to test without a mouse “*/ .a11y-tests-no-mouse, .a11y-tests-no-mouse *, .a11y-tests-no-mouse *:hover { cursor: none !important; pointer-events: none !important; } <html class=”a11y-tests-no-mouse” lang=”en”> … “</html> @mmatuzo

Slide 50

Slide 50

Testing accessibility “/* Check if the page works without colors “*/ .a11y-tests-grayscale { filter: grayscale(100%) !important; }

<html class=”a11y-tests-grayscale” lang=”en”> … “</html> @mmatuzo

Slide 51

Slide 51

Testing accessibility @mmatuzo

Slide 52

Slide 52

Debugging accessibility @mmatuzo

Slide 53

Slide 53

Debugging accessibility Root element with empty or missing lang attribute. html:not([lang]), html[lang=” “], html[lang=”“], html:not(:lang(en)) { border: 10px solid red; } @mmatuzo

Slide 54

Slide 54

Debugging accessibility Images without alt attribute or alt attribute with an empty string as value. img:not([alt]), img[alt=” “] { border: 10px solid red; } @mmatuzo

Slide 55

Slide 55

Debugging accessibility Elements with the class .btn or .button that are not real HTML buttons. .btn:not(button):not([type=”button”]):not([type=”submit”]), .button:not(button):not([type=”button”]):not([type=”submit”]) { outline: 2px dashed red; outline-offset: 2px; } @mmatuzo

Slide 56

Slide 56

Debugging accessibility Elements with the class .btn or .button that are not real HTML buttons. .btn:not(button):not([type=”button”]):not([type=”submit”]), .button:not(button):not([type=”button”]):not([type=”submit”]) { outline: 2px dashed red; outline-offset: 2px; } @mmatuzo

Slide 57

Slide 57

Debugging accessibility Elements with the class .btn or .button that are not real HTML buttons. .btn:not(button):not([type=”button”]):not([type=”submit”]), .button:not(button):not([type=”button”]):not([type=”submit”]) { outline: 2px dashed red; outline-offset: 2px; } @mmatuzo

Slide 58

Slide 58

Debugging accessibility Elements with the class .btn or .button that are not real HTML buttons. .btn:not(button):not([type=”button”]):not([type=”submit”]), .button:not(button):not([type=”button”]):not([type=”submit”]) { outline: 2px dashed red; outline-offset: 2px; } @mmatuzo

Slide 59

Slide 59

Debugging accessibility Tabindex higher than 0. [tabindex]:not([tabindex=”0”]):not([tabindex=”-1”]) { outline: 2px dashed orange; outline-offset: 2px; } @mmatuzo

Slide 60

Slide 60

Debugging accessibility Buttons nested in links or links nested in buttons. a button, button a { border: 10px solid red; } @mmatuzo

Slide 61

Slide 61

HTMHell - htmhell.dev @mmatuzo

Slide 62

Slide 62

a11y.css - github.com/ffoodd/a11y.css @mmatuzo

Slide 63

Slide 63

<CSS> and Semantics @mmatuzo

Slide 64

Slide 64

CSS and semantics - display: flex <table> <tr> <th>Name”</th>

<th>Age”</th> <th>Location”</th> <td>24”</td> <td>Austria”</td> <td>42”</td> <td>USA”</td> “</tr> <tr> <td>Sandra”</td> “</tr> <tr> <td>Mike”</td> “</tr> “</table> @mmatuzo

Slide 65

Slide 65

CSS and semantics - display: flex @mmatuzo

Slide 66

Slide 66

CSS and semantics - display: flex tr { display: flex; } @mmatuzo

Slide 67

Slide 67

CSS and semantics - display: flex @mmatuzo

Slide 68

Slide 68

CSS and semantics - list-style: none ul { list-style-type: none; } @mmatuzo

Slide 69

Slide 69

CSS and semantics - list-style: none @mmatuzo

Slide 70

Slide 70

@mmatuzo

Slide 71

Slide 71

CSS and semantics - speak-as span { speak-as: digits; } @mmatuzo

Slide 72

Slide 72

Thank you! ❤ matuzo.at @mmatuzo @mmatuzo