Skip to content

Instantly share code, notes, and snippets.

@fabriciofmsilva
Last active September 14, 2019 19:27
Show Gist options
  • Save fabriciofmsilva/0c3514bb7be3327758c7ee3ee0dd8950 to your computer and use it in GitHub Desktop.
Save fabriciofmsilva/0c3514bb7be3327758c7ee3ee0dd8950 to your computer and use it in GitHub Desktop.
Web Accessibility | Udacity

i# Accessibility

Web Content Accessibility Guidelines 2.0 (WCAG)

Principles (POUR)

  1. Perceivable
  2. Operable
  3. Understandable
  4. Robust

Topics

  • Focus on keyboard
  • Semantics
  • Styling and visual design

Resources

  • ChromeVox

Focus

Focus determines where keyboard events go in the page

Move focus around the page using your keyboard:

https://webaim.org/standards/wcag/checklist#sc2.1.1

What is focus?

  • TAB will move focus forward
  • SHIFT - TAB will move focus backwards
  • Arrow keys can be used to navigate inside of a component

Tab order

Implicity focusable automatically in the tab order + built-in keyboard event handling

Not all elements are focusable

Experiencing focus

http://udacity.github.io/ud891/lesson2-focus/01-basic-form/?tType=1&fName=Fabr%C3%ADcio&addressTxt=Tete&depCity=Sydney&arrCity=Melbourne&dDate=2017-12-10&rDate=2017-10-23&seatType=2

DOM Order Matters

WebAIM checklist items:

1.3.2: http://webaim.org/standards/wcag/checklist#sc1.3.2

Fixing DOM Order

Using tabindex

tabindex on MDN

https://www.w3.org/TR/html5/editing.html#sequential-focus-navigation-and-the-tabindex-attribute

tabindex="-1"

  • not in the natural tab order
  • can be programmatically focused with focus() method

tabindex="0"

  • in the natural tab order
  • can be programmatically focused

tabindex="5"

  • in the natural tab order
  • jumped to the front of tab order
  • anti-pattern! (can be confusing for screen reader users)

Deciding whats in focus

Focus behavior in interactive controls

Which Elements Should Have Focus?

Managing focus

You can skip ahead to Lesson 6 to learn how to change or remove the focus ring from an element. In this case, since we're managing focus and headers are typically not interactive it's probably OK to remove their focus ring. However, you should never remove the focus indicator from an interactive element unless you're going to replace it with something else. Otherwise a keyboard user might have no idea which element is currently focused!

Manage Focus Yourself

Skip links

You can read more about skip links in this article on the Web AIM site.

https://webaim.org/techniques/skipnav/

https://developers.google.com/web/updates/2016/03/focus-start-point?hl=en

<a href="#maincontent" class="skip-link">Skip to main content</a>
<nav>
  ...
</nav>
<main id="maincontent" tabindex="-1">
  ...
</main>
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background-color: #bf1722;
  color: white;
  padding: 8px;
  z-index: 100;
}

.skip-link:focus {
  top: 0;
}

Focus in complex components

The ARIA Authoring Practices doc (or "ARIA Design Patterns doc") is a great resource for figuring out what kind of keyboard support your complex components should implement.

WAI-ARIA Authoring Practices

https://www.w3.org/TR/wai-aria-practices/

Keyboard design patterns

Take a look at the ARIA Authoring Best Practices guide to read more about the Radio pattern.

ARIA Authoring Best Practices (Radio Group)

https://www.w3.org/TR/wai-aria-practices-1.1/#radiobutton

https://www.w3.org/TR/wai-aria-practices/#aria_ex

Roving focus

<li tabindex="0" checked>
<li tabindex="-1">
<li tabindex="-1">
<li tabindex="-1">
<li tabindex="-1">

<li tabindex="-1">
<li tabindex="0" checked> .focus()
<li tabindex="-1">
<li tabindex="-1">
<li tabindex="-1">

Offscreen content

To find your missing focus you can type the following into your console:

document.activeElement

Read more about Document.activeElement on MDN https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/activeElement

display: none; or visibility: hidden; display: block; or visibility: visible;

Implementing Offscreen Content

Modals and keyboard traps

WebAIM checklist items:

https://webaim.org/standards/wcag/checklist#sc2.1.2

on MDN https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog

Semantics basics

Semantics introduction

Assistive technology

  • devices
  • softwares
  • tools

screen reader, braille display, magnification, voice control, switch access, sip and puff, eye tracking

Programatically expressd semantics

Affordances

Experiencing Affordances

Semantics and assistive technologies

https://www.w3.org/TR/WCAG21/#name-role-value

Experience using a screenreader

Role, name, value

Role, Name, State, Value

(N) Round trip, (S) selected, (R) radio button

(N) Full name, (R) edit text,

(V) No preference, (N) Prefered seat type, (S) collapsed, (R) combo box

(N) Search, (R) button

The accessibility tree

main
├── form
|   ├── radio button { name: "Round trip", state: selected }
|   ├── edit text { name: "Full name" }
|   ├── combo box { value: "No preference", name: "Seat type", state: collapsed }
|   ├── button { name: "Search" }

Matching a Simple DOM and Ally Tree

Semantics in native HTML

implicit semantic meaning

Writing Semantic HTML Quiz

Writing Semantic HTML: The Name Game

WebAIM Guideline 1.1: http://webaim.org/standards/wcag/checklist#g1.1

The MDN page on demonstrates the two options for associating a with the thing it's labelling. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label

The W3C spec has a list of what types of elements work with a tag. https://www.w3.org/TR/html5/forms.html#category-label

Visible labels and Text alternative (not visible)

Labeling Input Elements

Text Alternatives

WebAIM checklist items:

JavaScript headings snippet:

var hs = document.querySelectorAll('h1,h2,h3,h4,h5,h6');
for (var i = 0; i < hs.length; i++) {
   console.log(hs[i].textContent.trim() + " " +  
               hs[i].tagName,
               hs[i]);
}

Labeling Images With alt Text

Lesson 3 Outro

Lesson 4: Navigation Content

Semantics - Navigating content - Intro

Navigating with a screen reader

Shortcuts mentioned:

  • CMD+F5 to turn on VoiceOver on OS X
  • Normal keyboard operation (TAB, Shift+TAB, arrow keys etc.) work as normal with VoiceOver running
  • CMD+L to jump to address bar
  • CTRL+Option+U to open Web Rotor
  • Type search term with Web Rotor open to search within Web Rotor
  • CTRL + Option + ← ↑ ↓ → to explore content
  • CTRL + Option + CMD + H to move forward by heading
  • CTRL + Option + CMD + Shift + H to move backward by heading

WebAIM's article on Using VoiceOver to evaluate Web Accessibility has a full introduction to VoiceOver from the point of view of evaluating accessibility, including most keyboard commands available. https://webaim.org/articles/voiceover/

If you don't have a Mac device, NVDA is a free, open source screen reader available for Windows. WebAIM's introduction to NVDA covers the basics of using NVDA to check accessibility. https://www.nvaccess.org/ https://webaim.org/articles/nvda/

If you only use Linux, Orca is available in the Gnome desktop manager, although this screen reader is much more rarely used and suffers from poor support by web browsers. https://help.gnome.org/users/orca/stable/

Navigating by headers

Using headings

WebAIM checklist items:

JavaScript headings snippet:

for (var i = 0, headings = $$('h1,h2,h3,h4,h5,h6');
     i < headings.length; i++) {
   console.log(headings[i].textContent.trim() + " " +  
               headings[i].tagName,
               headings[i]);
}

Using headings

Other navigational options

Other navigational options example

Shortcuts mentioned:

  • CTRL+Option+U to open Web Rotor
  • ← and → to change panes within Web Rotor
  • Type search term with Web Rotor open to search within Web Rotor
  • Enter to move VoiceOver focus to item from Web Rotor
  • CTRL + Option + Spacebar to activate link/button/other element
  • CTRL + Option + ← ↑ ↓ → to explore content
  • CTRL + Option + CMD + H to move forward by heading
  • CTRL + Option + CMD + Shift + H to move backward by heading
  • CTRL + Option + W to have a word spelled out

WebAIM's article on accesskey: http://webaim.org/techniques/keyboard/accesskey

WebAIM's articles on VoiceOver and NVDA:

http://webaim.org/articles/voiceover/ http://webaim.org/articles/nvda

Link text

WebAIM checklist item 2.4.9: http://webaim.org/standards/wcag/checklist#sc2.4.9

link anti-patterns (1)

<span class="link" onclick="doSomething()">I'm not a link</a>

<a onclick="changeView()">You might think I'm a link, but I'm not either</a>

link pattern

<a href="#internal">Now I'm a link</a>
  • shows up in links list
  • works with the keyboard
  • can be bookmarked

link anti-patterns (2)

   v code smell
<a href="#" onclick="doSomething()">Do something</a>

<button class="link" onclick="doSomething()">Do something</button>

link anti-patterns (3)

<a href="/">
  <img src="logo_wordmark.svg" alt="Udacity">
</a>

link (text) anti-pattern

Responsive layouts
lorem
<a>Read more</a>

link (text) pattern

Responsive layouts
lorem
<a>Read more about responsive layout</a>

<!-- or  -->

<a>Responsive layouts</a>
lorem

Exercise: Link Text

Landmarks

<header>
  <nav>
<main>
  <section>
    <article>
      <aside>
  <section>
    <hx>
<footer>

Outro Lesson 4

  1. Make sure to use meaningful headings and link text as well as good pay structure
  2. You shouldn't try to control the experience a screen reader user will have

Lesson 5: ARIA

Introduction semantics: ARIA

  • DOM Order
  • Focus
  • Keyboard
  • Semantics
  • Labeling
  • Headings
  • Landmarks
  • Links

Why ARIA

ARIA spec https://www.w3.org/TR/wai-aria-1.1/

You can play with this example yourself, if you want! http://udacity.github.io/ud891/lesson5-semantics-aria/02-why-aria/index.html

<label>
  <input type="radio" checked name="tType" value="0">
  Round Trip
</label>

"Round Trip, selected, radio button"

WAI-ARIA -> Web Accessibility Initiative - Accessible Rich Internet Applications

<label>
  <input type="checkbox">
  Receive promotional offers
</label>

checkbox
-> name: "Receive promotional offers"
-> state: checked
<div class="checkbox checked">
  Receive promotional offers
</div>

text
value: Receive promotional offers

<div class="checkbox checked" tabindex="0" role="checkbox" aria-checked="true">
  Receive promotional offers
</div>
  • ✅ modify accessibility tree
  • ❌ modify element appearance
  • ❌ modify element behaviour
  • ❌ add focusability
  • ❌ add keyboard event handling

First Steps with ARIA

What can ARIA do for you?

ARIA spec https://www.w3.org/TR/wai-aria-1.1/

Modify semantics

<button class="toggle" checked>
  Enable
</button>

button
-> name: Enable

<button class="toggle" checked role="switch" aria-checked="true">
  Enable
</button>

switch
-> name: Enable
-> state: checked

Express more UI semantics

<ul role="tree">
  <li role="treeitem" aria-expanded="true">
    Accessibility course
  </li>
  <ul role="group">
    <li role="treeitem" aria-expanded="false">
      Introduction
    </li>
    <li role="treeitem" aria-expanded="false">
      Focus
    </li>
  </ul>
</ul>

Extra label and descriptions

<button class="glyph" aria-label="Filter">
  <div class="menu-glyph"></div>
</button>

button
-> name: "Filter"

Relationships

<button aria-expanded="false" aria-controls="advanced-settings">
  <h2>Advanced setting</h2>
</button>
<div id="advanced-setting">
  ...
</div>

Live updates

<div role="alert">
  Could not connect!
</div>

Roleplaying

Default Semantics and Landmarks

ARIA in HTML spec, including guidance on what ARIA roles may and may not be used with which HTML elements: https://www.w3.org/TR/html-aria/

ARIA Relationships

https://www.w3.org/TR/wai-aria-1.1/#attrs_relationships

Combo Box

https://accessibilityresources.org/aria-setsize

Hidden In Plain Sight

For more information on screen reader-only text, check out WebAIM's article on "invisible content".

Name That Element Round 2

https://www.w3.org/TR/wai-aria-1.1/#aria-hidden

https://html.spec.whatwg.org/multipage/interaction.html#the-hidden-attribute

https://developer.paciellogroup.com/blog/2012/05/html5-accessibility-chops-hidden-and-aria-hidden/

https://www.w3.org/TR/wai-aria-1.1/#aria-labelledby

https://www.w3.org/TR/wai-aria-1.1/#treeitem

https://www.w3.org/TR/wai-aria-1.1/#button

https://www.w3.org/TR/wai-aria-1.1/#checkbox

Recap so far

Introducing ARIA Live

Check out the number input demo yourself, if you like.

aria-live="off"
aria-live="polite"
aria-live="assertive"

Atomic Relevant Busy

aria-atomic="true|false(default)"
aria-relevante="additions|removals|text|all|additions text(default)"
aria-busy="true|false"

Style

Introduction to Style

Working with focus styles

WebAIM checklist items:

2.4.7: http://webaim.org/standards/wcag/checklist#sc2.4.7

:focus pseudo-class https://developer.mozilla.org/en-US/docs/Web/CSS/:focus

outline CSS property https://developer.mozilla.org/en-US/docs/Web/CSS/outline

:hover pseudo-class https://developer.mozilla.org/en-US/docs/Web/CSS/:hover

::before pseudo-element https://developer.mozilla.org/en-US/docs/Web/CSS/::before

Input Modality

:moz-focusring pseudo-class https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-focusring

Proposing CSS input modality article http://radar.oreilly.com/2015/08/proposing-css-input-modailty.html

Input modality shim https://github.com/alice/modality

Styling with ARIA, I

CSS attribute selectors https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors

Author's note:

Just noticed in this example that we left off tabindex="0" (hopefully you caught that as well)! When you're building custom controls be sure to include tabindex so keyboard users can easily interact with the elements.

Responsive design for multi-device

WebAIM checklist items:

1.4.4: http://webaim.org/standards/wcag/checklist#sc1.4.4

Udacity course on Responsive Web Design Fundamentals https://www.udacity.com/course/responsive-web-design-fundamentals--ud893

Responsive web design basics on Web Fundamentals https://developers.google.com/web/fundamentals/design-and-ux/ux-basics/

Material Design Accessibility recommendations for touch targets https://material.google.com/usability/accessibility.html#accessibility-layout

Author's Note: On older browsers (particularly Mobile Safari) developers would add user-scaleable=no because it would disable the 350ms click delay in that browser. As of Safari 9.1 this is no longer the case, and using width=device-width in your viewport will handle removing that click delay.

Mobile Screen Readers

Since we’re on the subject of responsive design, I thought it would be a good chance for us to get our hands dirty and try out a mobile screen reader. I’m going to walk you through the steps of enabling the screen reader on both iOS and Android and in the next lesson you’ll need to do some basic screen reader commands to navigate to a secret element on the page.

Note that if you’re on an Android device, you can skip straight to the Android tutorial. And if you’re on an iOS device, you can skip to the iOS tutorial.

After you’ve learned how to turn on your screen reader, feel free to move on to the Using Mobile Screen Readers exercise.

Mobile Screen Readers iOS

Mobile Screen Readers Android

Segue to Color & Contrast

Meeting Contrast Requirements

WebAIM checklist items:

1.4.3: http://webaim.org/standards/wcag/checklist#sc1.4.3

1.4.6: http://webaim.org/standards/wcag/checklist#sc1.4.6

Don’t convey info with color alone

WebAIM checklist items:

1.4.1: http://webaim.org/standards/wcag/checklist#sc1.4.1

NoCoffee Chrome extension https://chrome.google.com/webstore/detail/nocoffee/jjeeggmbnhckmgdhmgdckeigabjfbddl?hl=en-US

For more information on color blindness, check out the Colour Blind Awareness site. http://www.colourblindawareness.org/colour-blindness/

Contrast Audit

High Contrast Mode

You can follow this link to get the Chrome High Contrast extension. Try it out on one of your sites to verify that everything works well for low vision users.

https://chrome.google.com/webstore/detail/high-contrast/djcfdncoelnlbldjfhinnjlhdjlikmph?hl=en

Author's Note: The example that shows a "subtle background color" in the navbar really does have a background color, we promise! It doesn't show up very well on YouTube, which I guess proves the point that just because a subtle color might look good on your screen doesn't always mean it'll look good on someone else's monitor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment