├── .gitignore ├── CHANGELOG.md ├── README.md ├── lessons ├── 01-accessible-icon-buttons │ ├── css │ │ └── demo.css │ ├── index.html │ └── package.json ├── 02-accessible-button-events │ ├── css │ │ └── demo.css │ ├── demo.js │ ├── index.html │ ├── lib │ │ └── angular.js │ └── package.json ├── 03-building-forms-with-accessibility-in-mind │ ├── css │ │ └── demo.css │ ├── index.html │ └── package.json ├── 04-headings-and-semantic-structure-for-accessible-web-pages │ ├── info.txt │ └── package.json ├── 05-focus-management-using-css-html-and-javascript │ ├── index.html │ ├── package.json │ ├── script.js │ └── style.css ├── 06-what-is-the-accessibility-tree │ ├── info.md │ └── package.json ├── 07-intro-to-aria │ ├── css │ │ └── demo.css │ ├── index.html │ └── package.json ├── 08-how-visible-vs-hidden-elements-affect-keyboard-screen-reader-users │ ├── css │ │ └── demo.css │ ├── index.html │ └── package.json ├── 09-using-the-voiceover-screen-reader-to-test-for-accessibility │ ├── info.md │ └── package.json ├── 10-testing-for-accessibility-with-the-nvda-screen-reader-on-windows │ ├── info.md │ └── package.json ├── 11-creating-visual-skip-links-in-html-and-css │ ├── css │ │ └── demo.css │ ├── index.html │ └── package.json ├── 12-accessible-modal-dialogs │ ├── index.html │ ├── package.json │ ├── script.js │ └── style.css ├── 13-using-the-tabindex-attribute-for-keyboard-accessibility │ ├── index.html │ ├── package.json │ ├── script.js │ └── style.css ├── 14-basic-accessibility-testing │ ├── info.md │ └── package.json ├── 15-accessibility-testing-with-axe-cli │ ├── info.md │ └── package.json ├── 16-accessible-animations-with-reduced-motion │ ├── css │ │ └── style.css │ ├── index.html │ ├── package.json │ ├── reduce-motion.js │ └── style.scss └── 17-what-is-accessible-name-calculation │ ├── css │ └── demo.css │ ├── index.html │ └── package.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 4 | 5 | ## 1.0.0 - 2019-07-27 6 | 7 | All notable changes to "Start Building Accessible Web Applications Today” will be documented in this file. 8 | 9 | ### Added 10 | 11 | - Created this repository. 12 | - Added this CHANGELOG file. 13 | - Added individual lessons as folders to be included under the master branch. 14 | - Added small `package.json` files for all lessons including their lesson names. 15 | - Added `info.md` file to lessons 4, 6, 9, 10, 14, 15, which include links/commands demonstrated in the lesson to enhance user experience. 16 | - Added `` line to the `index.html` on lesson 07. 17 | - Added `` line and `` line to the `index.html` on lesson 13. 18 | - Added third button code to match lesson 13 finished code, as it was previously matching the middle of the video. 19 | 20 | ### Changed 21 | 22 | - Changed `dialog-polyfill#0.4.5->0.5.0`. 23 | - Changed `wicg-inert#1.1.0->2.1.2`. 24 | - Corrected both file paths in lesson 12 for the scripts imported. First script changed: `` -> ``. Second script changed: `` -> ``. 25 | - Changed `scripts.js` in lesson 12 to match lesson's code, as it was simply incorrect. 26 | 27 | ### Removed 28 | 29 | - None. 30 | 31 | ### Deprecated 32 | 33 | - None. 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | These lessons can be run locally or with the links provided on codepen. 2 | 3 | [Lesson 01 - accessible-icon-buttons](https://codepen.io/cayden-egghead/pen/OKWWqK) 4 | 5 | [Lesson 02 - accessible-button-events](https://codepen.io/cayden-egghead/pen/NQddQG) 6 | 7 | [Lesson 03 - building-forms-with-accessibility-in-mind](https://codepen.io/cayden-egghead/pen/YmNNmB) 8 | 9 | [Lesson 05 - focus-management-using-css-html-and-javascript](https://codepen.io/cayden-egghead/pen/XvpMrz) 10 | 11 | [Lesson 07 - intro-to-aria](https://codepen.io/cayden-egghead/pen/NQdpWx) 12 | 13 | [Lesson 08 - how-visible-vs-hidden-elements-affect-keyboard-screen](https://codepen.io/cayden-egghead/pen/xvgqxj) 14 | 15 | [Lesson 11 - creating-visual-skip-links-in-html-and-css](https://codepen.io/cayden-egghead/pen/LwxWEg) 16 | 17 | [Lesson 12 - accessible-modal-dialogs](https://codepen.io/cayden-egghead/pen/zgNZGR) 18 | 19 | [Lesson 13 - using-the-tabindex-attribute-for-keyboard-accessibility](https://codepen.io/cayden-egghead/pen/zgNZvR) 20 | 21 | [Lesson 16 - accessible-animations-with-reduced-motion](https://codepen.io/cayden-egghead/pen/NQdpxN) 22 | 23 | [Lesson 17 - what-is-accessible-name-calculation](https://codepen.io/cayden-egghead/pen/oKBZbJ) 24 | -------------------------------------------------------------------------------- /lessons/01-accessible-icon-buttons/css/demo.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-family: Helvetica, sans-serif; 3 | text-align: center; 4 | } 5 | main { 6 | padding: 1em; 7 | } 8 | .icon { 9 | display: block; 10 | width: 3em; 11 | height:2.6em; 12 | fill: currentColor; 13 | } 14 | .icon-help { 15 | background: url(https://jsbin-user-assets.s3.amazonaws.com/marcysutton/question.svg) no-repeat center center; 16 | background-size: contain; 17 | } 18 | button, .button { 19 | background-color: buttonface; 20 | border: 2px outset buttonface; 21 | box-sizing: border-box; 22 | display: inline-block; 23 | font-weight: bold; 24 | font-size: 24px; 25 | height: 3em; 26 | line-height: 3em; 27 | padding: 3px 6px 6px; 28 | vertical-align: middle; 29 | -webkit-appearance: button; 30 | } 31 | .visuallyhidden { 32 | border: 0; 33 | clip: rect(0 0 0 0); 34 | height: 1px; 35 | margin: -1px; 36 | overflow: hidden; 37 | padding: 0; 38 | position: absolute; 39 | width: 1px; 40 | } 41 | -------------------------------------------------------------------------------- /lessons/01-accessible-icon-buttons/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Button Demo 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 16 | 17 | 18 | 21 | 22 |
23 | 24 | Help! 25 | 26 | 27 |
28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /lessons/01-accessible-icon-buttons/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "01-accessible-icon-buttons", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/02-accessible-button-events/css/demo.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-family: Helvetica, sans-serif; 3 | text-align: center; 4 | } 5 | main { 6 | padding: 1em; 7 | } 8 | .icon { 9 | display: block; 10 | width: 3em; 11 | height:2.6em; 12 | fill: currentColor; 13 | } 14 | .icon-menu { 15 | background: url(https://jsbin-user-assets.s3.amazonaws.com/marcysutton/menu.svg) no-repeat center center; 16 | background-size: contain; 17 | } 18 | .icon-help { 19 | background: url(https://jsbin-user-assets.s3.amazonaws.com/marcysutton/question.svg) no-repeat center center; 20 | background-size: contain; 21 | } 22 | button, .button { 23 | background-color: buttonface; 24 | border: 2px outset buttonface; 25 | box-sizing: border-box; 26 | display: inline-block; 27 | font-weight: bold; 28 | font-size: 24px; 29 | height: 3em; 30 | line-height: 3em; 31 | padding: 3px 6px 6px; 32 | vertical-align: middle; 33 | -webkit-appearance: button; 34 | } 35 | -------------------------------------------------------------------------------- /lessons/02-accessible-button-events/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('demoApp', []) 2 | .controller('demoController', function($scope) { 3 | $scope.doStuff = function($event){ 4 | alert('do stuff'); 5 | }; 6 | }); 7 | -------------------------------------------------------------------------------- /lessons/02-accessible-button-events/index.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | Button Demo 8 | 9 | 10 | 11 |
12 | 15 | 16 |
17 | 18 |
19 |
20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /lessons/02-accessible-button-events/lib/angular.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggheadio-projects/start-building-accessible-web-applications-today/5561a916841d2e95f7bea48cd04ffb2119288f42/lessons/02-accessible-button-events/lib/angular.js -------------------------------------------------------------------------------- /lessons/02-accessible-button-events/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "02-accessible-button-events", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/03-building-forms-with-accessibility-in-mind/css/demo.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-family: Helvetica, sans-serif; 3 | } 4 | main { 5 | padding: 1em; 6 | } 7 | .label-wrap { 8 | margin-top: 1em; 9 | display: inline-block; 10 | } 11 | .input-wrap { 12 | display: inline-block; 13 | } 14 | fieldset { 15 | margin: 1em 0; 16 | } 17 | .visuallyhidden { 18 | border: 0; 19 | clip: rect(0 0 0 0); 20 | height: 1px; 21 | margin: -1px; 22 | overflow: hidden; 23 | padding: 0; 24 | position: absolute; 25 | width: 1px; 26 | } 27 | -------------------------------------------------------------------------------- /lessons/03-building-forms-with-accessibility-in-mind/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | JS Bin 7 | 8 | 9 |
10 |

Accessible Form Demo

11 | 12 |
13 | 17 | 18 |
19 | Favorite animal 20 |
21 | 25 |
26 |
27 | 31 |
32 |
33 | 37 |
38 |
39 |
40 | 43 |
44 |
45 | 46 |
47 |
48 |
49 | 50 | 51 | -------------------------------------------------------------------------------- /lessons/03-building-forms-with-accessibility-in-mind/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "03-building-forms-with-accessibility-in-mind", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/04-headings-and-semantic-structure-for-accessible-web-pages/info.txt: -------------------------------------------------------------------------------- 1 | This file contains links and commands demonstrated in the following lesson. 2 | 3 | https://en.wikipedia.org/wiki/Main_Page 4 | -------------------------------------------------------------------------------- /lessons/04-headings-and-semantic-structure-for-accessible-web-pages/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "04-headings-and-semantic-structure-for-accessible-web-pages", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/05-focus-management-using-css-html-and-javascript/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Focus management 6 | 7 | 8 | 9 |
10 | 14 |
15 |

Focus Management

16 |
17 |
18 |

Main content

19 |

A link.

20 | 31 |
32 | 35 |
36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /lessons/05-focus-management-using-css-html-and-javascript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "05-focus-management-using-css-html-and-javascript", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/05-focus-management-using-css-html-and-javascript/script.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | 3 | var list = $('ul'), 4 | listItems = list.find('li'); 5 | 6 | $('.btn-delete').on('click', function() { 7 | $(this).parent().remove(); 8 | listItems.find('.btn-delete').first().focus(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /lessons/05-focus-management-using-css-html-and-javascript/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-family: sans-serif; 3 | } 4 | ul.list { 5 | padding: 0; 6 | } 7 | ul.list li { 8 | border: 1px solid #ccc; 9 | border-width: 1px 1px 0; 10 | display: flex; 11 | list-style-type: none; 12 | margin: 0; 13 | padding: 1em; 14 | } 15 | ul.list li:last-child { 16 | border-bottom-width: 1px; 17 | } 18 | .btn-delete { 19 | background-color: #ddd; 20 | border: none; 21 | margin-left: auto; 22 | padding: 1em; 23 | -webkit-appearance: none; 24 | } 25 | .btn-delete:before { 26 | content: 'X'; 27 | display: block; 28 | font-weight: bold; 29 | } 30 | 31 | [tabindex="-1"] { 32 | outline: 0; 33 | } 34 | ul.skip-links { 35 | list-style: none; 36 | position: absolute; 37 | } 38 | ul.skip-links a { 39 | background-color: #fff; 40 | display: block; 41 | left: -999999px; 42 | padding: 1em; 43 | position: absolute; 44 | } 45 | ul.skip-links a:focus { 46 | left: 0; 47 | } 48 | -------------------------------------------------------------------------------- /lessons/06-what-is-the-accessibility-tree/info.md: -------------------------------------------------------------------------------- 1 | This file contains links and commands demonstrated in the following lesson. 2 | 3 | https://egghead.io/search 4 | 5 | https://marcysutton.com/ 6 | -------------------------------------------------------------------------------- /lessons/06-what-is-the-accessibility-tree/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "06-what-is-the-accessibility-tree", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/07-intro-to-aria/css/demo.css: -------------------------------------------------------------------------------- 1 | button, .button, custom-button { 2 | background-color: buttonface; 3 | border: 2px outset buttonface; 4 | box-sizing: border-box; 5 | display: inline-block; 6 | font-family: sans-serif; 7 | font-weight: bold; 8 | font-size: 24px; 9 | height: 2em; 10 | line-height: 2em; 11 | padding: 3px 6px 6px; 12 | margin: 1em 0; 13 | vertical-align: middle; 14 | -webkit-appearance: button; 15 | } 16 | custom-button[aria-label="Close"]:before { 17 | content: 'X'; 18 | display: block; 19 | } 20 | custom-button[aria-disabled="true"] { 21 | color: graytext; 22 | pointer-events: false; 23 | } 24 | -------------------------------------------------------------------------------- /lessons/07-intro-to-aria/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Intro to ARIA 5 | 6 | 7 | 8 |
9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /lessons/07-intro-to-aria/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "07-intro-to-aria", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/08-how-visible-vs-hidden-elements-affect-keyboard-screen-reader-users/css/demo.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-family: Helvetica, sans-serif; 3 | text-align: center; 4 | } 5 | 6 | .visuallyhidden { 7 | border: 0; 8 | clip: rect(0 0 0 0); 9 | height: 1px; 10 | margin: -1px; 11 | overflow: hidden; 12 | padding: 0; 13 | position: absolute; 14 | width: 1px; 15 | } 16 | div { 17 | color: #fff; 18 | height: 100px; 19 | float: left; 20 | padding-bottom: 2%; 21 | width: 200px; 22 | } 23 | div:before { 24 | content: ''; 25 | display: block; 26 | height: 35%; 27 | } 28 | div:nth-child(1) { 29 | background-color: purple; 30 | } 31 | div:nth-child(2) { 32 | background-color: red; 33 | } 34 | div:nth-child(3) { 35 | background-color: blue; 36 | } 37 | div:nth-child(4) { 38 | background-color: green; 39 | } 40 | div:nth-child(5) { 41 | background-color: yellow; 42 | color: #000; 43 | } 44 | div:nth-child(6) { 45 | background-color: orange; 46 | color: #000; 47 | } 48 | div:nth-child(5) a, 49 | div:nth-child(6) a { 50 | color: #000; 51 | } 52 | div h1 { 53 | margin: 0; 54 | } 55 | div a { 56 | color: #fff; 57 | display: block; 58 | font-size: 1em; 59 | font-weight: bold; 60 | padding: 0.5em; 61 | } 62 | div button, { 63 | background-color: #000; 64 | border: 0; 65 | color: #fff; 66 | font-size: 1em; 67 | padding: 0.5em; 68 | } 69 | div button:focus { 70 | background-color: #fff; 71 | color: #000; 72 | } 73 | -------------------------------------------------------------------------------- /lessons/08-how-visible-vs-hidden-elements-affect-keyboard-screen-reader-users/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Visible vs. Hidden 5 | 6 | 7 | 8 | 9 |
10 |

Heading

11 | Link 1 12 |
13 | 17 |
18 |

Heading

19 | Link 3 20 |
21 |
22 |

Heading

23 | Link 4 24 |
25 |
26 |

Heading

27 | Link 5 28 |
29 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /lessons/08-how-visible-vs-hidden-elements-affect-keyboard-screen-reader-users/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "08-how-visible-vs-hidden-elements-affect-keyboard-screen-reader-users", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/09-using-the-voiceover-screen-reader-to-test-for-accessibility/info.md: -------------------------------------------------------------------------------- 1 | This file contains links and commands demonstrated in the following lesson. 2 | 3 | https://www.nytimes.com/ 4 | 5 | https://webaim.org/articles/voiceover/ 6 | 7 | https://www.apple.com/voiceover/info/guide/_1131.html 8 | -------------------------------------------------------------------------------- /lessons/09-using-the-voiceover-screen-reader-to-test-for-accessibility/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "09-using-the-voiceover-screen-reader-to-test-for-accessibility", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/10-testing-for-accessibility-with-the-nvda-screen-reader-on-windows/info.md: -------------------------------------------------------------------------------- 1 | This file contains links and commands demonstrated in the following lesson. 2 | 3 | https://en.wikipedia.org/wiki/Main_Page 4 | -------------------------------------------------------------------------------- /lessons/10-testing-for-accessibility-with-the-nvda-screen-reader-on-windows/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "10-testing-for-accessibility-with-the-nvda-screen-reader-on-windows", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/11-creating-visual-skip-links-in-html-and-css/css/demo.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-family: Helvetica, sans-serif; 3 | } 4 | .skip-links { 5 | list-style: none; 6 | margin: 0; 7 | padding: 0; 8 | position: relative; 9 | } 10 | .skip-links li a { 11 | background-color: #fff; 12 | display: block; 13 | left: -600000px; 14 | padding: 0.5em; 15 | position: absolute; 16 | } 17 | .skip-links li a:focus { 18 | left: 0; 19 | } 20 | [tabindex="-1"]:focus { 21 | outline: none; 22 | } 23 | -------------------------------------------------------------------------------- /lessons/11-creating-visual-skip-links-in-html-and-css/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Skip Links Demo 5 | 6 | 7 | 8 | 13 | 16 |
17 |

Homepage

18 |

Article Title

19 |
20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /lessons/11-creating-visual-skip-links-in-html-and-css/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "11-creating-visual-skip-links-in-html-and-css", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/12-accessible-modal-dialogs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Accessible Modal Dialogs 5 | 6 | 7 | 8 | 9 |
10 | 15 | 18 |
19 |

Homepage

20 |

Article Title

21 | 22 | 23 |
24 | 27 |
28 | 29 | 30 |

Dialog Title

31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /lessons/12-accessible-modal-dialogs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "12-accessible-modal-dialogs", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | "dialog-polyfill": "^0.5.0", 7 | "wicg-inert": "^2.1.2" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lessons/12-accessible-modal-dialogs/script.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", pageLoaded); 2 | 3 | function pageLoaded(event) { 4 | 5 | var dialogBtn = document.getElementById('dialogTrigger'), 6 | closeBtn = document.getElementById('closeBtn'), 7 | dialog = document.querySelector('dialog'); 8 | wrapper = document.querySelector('.wrapper'); 9 | 10 | dialogPolyfill.registerDialog(dialog); 11 | 12 | dialogBtn.addEventListener('click', dialogBtnHandler); 13 | closeBtn.addEventListener('click', dialogCloseBtnHandler); 14 | 15 | function dialogBtnHandler(event) { 16 | dialog.showModal(); 17 | 18 | document.addEventListener('keydown', keydownHandler); 19 | wrapper.setAttribute('inert', ''); 20 | } 21 | 22 | function dialogCloseBtnHandler(event) { 23 | closeDialog(); 24 | } 25 | 26 | function closeDialog() { 27 | dialog.close(); 28 | 29 | setTimeout(function() { 30 | dialogBtn.focus(); 31 | }); 32 | 33 | wrapper.removeAttribute('inert'); 34 | } 35 | 36 | function keydownHandler(event) { 37 | if (event.keyCode === 27) { 38 | closeDialog() 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lessons/12-accessible-modal-dialogs/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-family: sans-serif; 3 | } 4 | .skip-links { 5 | list-style: none; 6 | margin: 0; 7 | padding: 0; 8 | position: relative; 9 | } 10 | .skip-links li a { 11 | background-color: #fff; 12 | display: block; 13 | left: -600000px; 14 | padding: 0.5em; 15 | position: absolute; 16 | } 17 | .skip-links li a:focus { 18 | left: 0; 19 | } 20 | [tabindex="-1"]:focus { 21 | outline: none; 22 | } 23 | -------------------------------------------------------------------------------- /lessons/13-using-the-tabindex-attribute-for-keyboard-accessibility/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tabindex Demo 5 | 6 | 7 | 8 |
Button
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /lessons/13-using-the-tabindex-attribute-for-keyboard-accessibility/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "13-using-the-tabindex-attribute-for-keyboard-accessibility", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/13-using-the-tabindex-attribute-for-keyboard-accessibility/script.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", pageLoaded); 2 | 3 | function pageLoaded() { 4 | var btn = document.getElementById('fakeBtn'); 5 | btn.addEventListener('click', btnEventHandler); 6 | btn.addEventListener('keydown', btnEventHandler); 7 | } 8 | 9 | function btnEventHandler(event) { 10 | console.log(event.type); 11 | 12 | var realBtn = document.getElementById('realBtn'); 13 | realBtn.focus(); 14 | } 15 | -------------------------------------------------------------------------------- /lessons/13-using-the-tabindex-attribute-for-keyboard-accessibility/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-family: sans-serif; 3 | } 4 | .btn { 5 | background-color: #ddd; 6 | border: none; 7 | display: inline-block; 8 | font-size: 1.5em; 9 | margin-left: auto; 10 | padding: 1em; 11 | -webkit-appearance: none; 12 | } 13 | -------------------------------------------------------------------------------- /lessons/14-basic-accessibility-testing/info.md: -------------------------------------------------------------------------------- 1 | This file contains links and commands demonstrated in the following lesson. 2 | 3 | https://www.nytimes.com/ 4 | 5 | https://addons.mozilla.org/en-US/firefox/addon/web-developer/ 6 | 7 | https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/ 8 | 9 | https://contrast-ratio.com/ 10 | -------------------------------------------------------------------------------- /lessons/14-basic-accessibility-testing/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "14-basic-accessibility-testing", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/15-accessibility-testing-with-axe-cli/info.md: -------------------------------------------------------------------------------- 1 | This file contains links and commands demonstrated in the following lesson. 2 | 3 | `npm install axe-cli -g` 4 | 5 | `axe www.deque.com` 6 | 7 | `axe https://dequeuniversity.com/demo/mars/` 8 | 9 | `axe https://dequeuniversity.com/demo/mars/ -b c` 10 | 11 | https://github.com/dequelabs/axe-cli 12 | -------------------------------------------------------------------------------- /lessons/15-accessibility-testing-with-axe-cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "15-accessibility-testing-with-axe-cli", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/16-accessible-animations-with-reduced-motion/css/style.css: -------------------------------------------------------------------------------- 1 | button#animation-toggle { 2 | background-color: black; 3 | border: none; 4 | border-radius: 0; 5 | color: white; 6 | font-size: 1em; 7 | padding: 0.5em 1em; 8 | } 9 | 10 | #animation-target { 11 | border: 1px solid; 12 | height: 400px; 13 | margin-bottom: 1em; 14 | overflow: hidden; 15 | position: relative; 16 | width: 600px; 17 | } 18 | 19 | .pulse { 20 | z-index: -1; 21 | position: absolute; 22 | top: 50%; 23 | left: 50%; 24 | transform: translate(-50%, -50%); 25 | max-width: 30rem; 26 | } 27 | .pulse circle { 28 | fill: #ff5154; 29 | transform: scale(0); 30 | opacity: 0.4; 31 | transform-origin: 50% 50%; 32 | animation: pulse 2.5s cubic-bezier(0.5, 0.5, 0, 1) infinite; 33 | } 34 | .pulse circle:nth-child(2) { 35 | fill: #7fc6a4; 36 | animation: pulse 2.5s 0.75s cubic-bezier(0.5, 0.5, 0, 1) infinite; 37 | } 38 | .pulse circle:nth-child(3) { 39 | fill: #e5f77d; 40 | animation: pulse 2.5s 1.5s cubic-bezier(0.5, 0.5, 0, 1) infinite; 41 | } 42 | 43 | @keyframes pulse { 44 | 25% { 45 | opacity: 0.4; 46 | } 47 | 100% { 48 | transform: scale(1); 49 | opacity: 0; 50 | } 51 | } 52 | .no-animate .pulse, .no-animate circle { 53 | animation: none !important; 54 | } 55 | .no-animate .pulse circle { 56 | opacity: 0.75; 57 | transform: scale(0.25); 58 | } 59 | .no-animate .pulse circle:nth-child(2) { 60 | opacity: 0.25; 61 | transform: scale(0.75); 62 | } 63 | .no-animate .pulse circle:nth-child(3) { 64 | opacity: 0.5; 65 | transform: scale(0.5); 66 | } 67 | 68 | /* if reduced-motion is selected on OSX/iOS */ 69 | @media (prefers-reduced-motion) { 70 | /* hide toggle button */ 71 | #animation-toggle { 72 | display: none; 73 | } 74 | 75 | /* make sure animations actually stop */ 76 | .pulse, circle { 77 | animation: none !important; 78 | } 79 | 80 | .pulse circle { 81 | opacity: 0.75; 82 | transform: scale(0.25); 83 | } 84 | 85 | .pulse circle:nth-child(2) { 86 | opacity: 0.25; 87 | transform: scale(0.75); 88 | } 89 | 90 | .pulse circle:nth-child(3) { 91 | opacity: 0.5; 92 | transform: scale(0.5); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /lessons/16-accessible-animations-with-reduced-motion/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Animation Demo 5 | 6 | 7 | 8 |
9 | 10 | Animating circles 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /lessons/16-accessible-animations-with-reduced-motion/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "16-accessible-animations-with-reduced-motion", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lessons/16-accessible-animations-with-reduced-motion/reduce-motion.js: -------------------------------------------------------------------------------- 1 | var animating = true; 2 | var animationTarget = document.getElementById('animation-target'); 3 | var toggleBtn = document.getElementById('animation-toggle'); 4 | var toggleBtnText = toggleBtn.querySelector('span'); 5 | toggleBtn.addEventListener('click', toggleBtnHandler); 6 | 7 | function toggleBtnHandler(event) { 8 | if (animating) { 9 | disableAnimation(); 10 | } else { 11 | enableAnimation(); 12 | } 13 | } 14 | function disableAnimation() { 15 | toggleBtnText.textContent = 'on'; 16 | animationTarget.classList.add('no-animate'); 17 | animating = false; 18 | localStorage.setItem('animating', 'false'); 19 | } 20 | function enableAnimation() { 21 | toggleBtnText.textContent = 'off'; 22 | animationTarget.classList.remove('no-animate'); 23 | animating = true; 24 | localStorage.setItem('animating', 'true'); 25 | } 26 | 27 | if (localStorage.getItem('animating') === 'false') { 28 | disableAnimation(); 29 | } 30 | -------------------------------------------------------------------------------- /lessons/16-accessible-animations-with-reduced-motion/style.scss: -------------------------------------------------------------------------------- 1 | button#animation-toggle { 2 | background-color: black; 3 | border: none; 4 | border-radius: 0; 5 | color: white; 6 | font-size: 1em; 7 | padding: 0.5em 1em; 8 | } 9 | #animation-target { 10 | border: 1px solid; 11 | height: 400px; 12 | margin-bottom: 1em; 13 | overflow: hidden; 14 | position: relative; 15 | width: 600px; 16 | } 17 | .pulse { 18 | z-index: -1; 19 | position: absolute; 20 | top: 50%; 21 | left: 50%; 22 | transform: translate(-50%, -50%); 23 | max-width: 30rem; 24 | 25 | circle { 26 | fill: #ff5154; 27 | transform: scale(0); 28 | opacity: 0.4; 29 | transform-origin: 50% 50%; 30 | animation: pulse 2.5s cubic-bezier(.5,.5,0,1) infinite; 31 | 32 | &:nth-child(2) { 33 | fill: #7fc6a4; 34 | animation: pulse 2.5s 0.75s cubic-bezier(.5,.5,0,1) infinite; 35 | } 36 | 37 | &:nth-child(3) { 38 | fill: #e5f77d; 39 | animation: pulse 2.5s 1.5s cubic-bezier(.5,.5,0,1) infinite; 40 | } 41 | 42 | } 43 | 44 | } 45 | 46 | @keyframes pulse { 47 | 25% { 48 | opacity: 0.4; 49 | } 50 | 51 | 100% { 52 | transform: scale(1); 53 | opacity: 0; 54 | } 55 | } 56 | 57 | @mixin noAnimate { 58 | .pulse, circle { 59 | animation: none !important; 60 | } 61 | .pulse circle { 62 | opacity: 0.75; 63 | transform: scale(0.25); 64 | } 65 | .pulse circle:nth-child(2) { 66 | opacity: 0.25; 67 | transform: scale(0.75); 68 | } 69 | .pulse circle:nth-child(3) { 70 | opacity: 0.5; 71 | transform: scale(0.5); 72 | } 73 | } 74 | .no-animate { 75 | @include noAnimate; 76 | } 77 | 78 | /* if reduced-motion is selected on OSX/iOS */ 79 | @media (prefers-reduced-motion) { 80 | /* hide toggle button */ 81 | #animation-toggle { 82 | display: none; 83 | } 84 | /* make sure animations actually stop */ 85 | @include noAnimate; 86 | } 87 | -------------------------------------------------------------------------------- /lessons/17-what-is-accessible-name-calculation/css/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | } 4 | -------------------------------------------------------------------------------- /lessons/17-what-is-accessible-name-calculation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Accessible Name Calculation 5 | 6 | 7 | 8 |

Accessible Name Calculation Demo

9 | 10 | 17 | 18 |

19 | 20 | Read more 21 | articles about cute animals 22 | 23 |

24 | 25 | 26 | 27 | X 28 | 29 |
30 | 31 |

Sign up your favorite friends for our newsletter!

32 |
33 |
34 | 35 | 36 |
37 | 38 |
39 | 43 |
44 | 45 |
46 | 50 |
51 |
52 | 53 |
54 |
55 |

Closing this dialog will cancel your submission.

56 |
57 | 58 | 59 | -------------------------------------------------------------------------------- /lessons/17-what-is-accessible-name-calculation/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "17-what-is-accessible-name-calculation", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "slug": "start-building-accessible-web-applications-today", 3 | "private": true, 4 | "repository": "https://github.com/eggheadio-projects/start-building-accessible-web-applications-today" 5 | } 6 | --------------------------------------------------------------------------------