The Seventh week

Here's what we're going today

  1. Attendance
  2. OCAS is coming
  3. Theory
    1. WAI-ARIA
    2. Accessibility in JS Frameworks
    3. Analyzing test results

OCAS

Tudor Whiteley will be coming in at noon today to meet you and address any questions you have in regards to the desktop+mouse testing.

WAI-ARIA deep dive

As we covered earlier, WAI-ARIA, a.k.a. ARIA, is a specification from the W3C that uses element attributes to supplement existing semantics

  1. to provide more information about your markup, and
  2. provide information about content that updates without a page refresh.
  3. This is especially relevant when you are using a front-end javascript framework (Angular, React, Vue, et al.).

Remember that the spec tells us that we should use native semantics when they are available.

If it's a button, use a < button >.

ARIA roles

The role attribute provides information about an element's purpose.

The role attribute identifies the element to the screenreader, but it does not recreate the native functionality. That's on you.

role="button"

Let's say, for whatever reason, you need to make a button out of something that's not < button >, < input type='button' />, < input type='submit' />, < input type='reset' /> or < input type='image' />.

role='button' identifies any element as a button to a screenreader. Use this in conjunction with tabindex='0' - the role itself does not make the element focusable.

Remember, too, that a native HTML button will fire an onclick event when space or enter are pressed - so you're also responsible for recreating that native functionality.

More roles! - widgets

checkbox

dialog (this can be a modal, or not)

link

log (i.e. a chat log)

marquee (like a log, but not vital or linear, i.e. a carousel or stock ticker)

progressbar

radio

scrollbar

slider (i.e. a range slider or volume control)

spinbutton (a value selection input with up and down arrows)

status (a status update message, i.e. `your changes have been saved`

tablist > tab + tabpanel

grid > row > rowheader + cell + columnheader

menubar > menu > menuitem + menuitemcheckbox

textbox

timer

tooltip

tree/treegrid > treeitem

switch identical to checkbox, but strictly for values of on or off

listbox > option

radiogroup > radio

Even more roles! - document structure

article

definition

directory (i.e. table of contents)

document

group (of UI elements not in a perceivable page section)

heading

img (useful in case of background images)

list > listitem

math (there is an entire markup language for mathy stuff! it's called MathML and can be called into other markup, like HTML)

note

presentation - similar in function to aria-hidden; this tells the screenreader that the element is decorative, but support for it on natively focusable elements is interesting.

region

separator

toolbar

And finally... more roles! - landmarks

application - for when your HTML document behaves completely different from a standard html document; probably don't use this. It turns off all standard keyboard shortcuts in most screenreaders.

banner - analogous to < header >

complementary - like < aside >

contentinfo - like < footer >

form

main

navigation

search

Widget attributes

role="combobox|textbox" aria-autocomplete="none|inline|list|both"

role="checkbox|switch|..." aria-checked="true|false|mixed"

aria-current="page|step|date|location|time|true|false"

aria-disabled="true|false"

aria-expanded="true|false"

aria-haspopup="true|false|menu|listbox|tree|grid|dialog"

aria-hidden="true|false|undefined"

aria-invalid="true|false|grammar|spelling"

aria-label={string} only for invisible text

role="grid|heading|listitem|row|tablist" aria-level={integer}

role="textbox" aria-multiline="true|false"

role="grid|listbox|tablist|tree" aria-multiselectable="true|false"

role="scrollbar|select|separator|slider|tablist|toolbar" aria-orientation="horizontal|vertical|undefined"

role="button" aria-pressed="true|false|mixed"

role=checkbox|combobox|grid|gridcell|listbox|radiogroup|slider|spinbutton|textbox" aria-readonly="true|false"

role="combobox|gridcell|listbox|radiogroup|spinbutton|textbox|tree" aria-required="true|false"

role="gridcell|option|row|tab" aria-selected="true|false|undefined"

role="columnheader|rowheader" aria-sort="ascending|descending|none|other"

role="range|scrollbar|separator|slider|spinbutton" aria-valuemax={number} aria-valuemin={number} aria-valuenow={number}

role="range|separator" aria-valuetext={string}

Live region attributes

aria-live="polite|assertive|off"

aria-live="polite" aria-atomic="true|false"

aria-live="polite" aria-relevant="additions|text|removals|all"

aria-live="assertive" aria-busy="true|false"

Implicit live region attributes

Several roles have implicit live region values:

role="alert" has an implicit aria-live="assertive"

role="status" and role="log" have an implicit aria-live="polite"

role="timer" and role="marquee" have an implicit aria-live="off"

These can be overridden by explicitly declaring aria-live values.

Relationship attributes

role="application|composite|group|textbox" aria-activedescendant={id}

aria-controls={id}

aria-describedby={id} similar to aria-labelledby, but verbose instead of concise

aria-labelledby={id}

aria-flowto={id} gives the user the option to move to an element, overriding the source order

aria-owns={id} Defines a parent-child relationship when one isn't semantically apparent. To understand how this is different from aria-controls, imagine a carousel. The arrows on the left and right would have aria-controls attributes. The dots at the bottom that correlate to individual slides would have aria-owns attributes.

role="article|listitem|menuitem|option|radio|tab" aria-setsize={integer} aria-posinset={integer} Only required when not all elements from the set are included in the DOM.

Accessibility in Front-end JS Frameworks

Today we're going to look at the big three.

Let's keep in mind that >4% of users in the WebAIM survey were using IE 6, 7 or 8.

Browser support of javascript frameworks
VueES5-compliant browsers - IE9+
ReactES5-compliant browsers - IE9 and IE10 require polyfills
AngularModern browsers. Safari 7 & 8, IE9, 10 & 11, Android 4.1+ require polyfills.

Progressive enhancement

Within the last year, we've seen companies like Airbnb and Groupon tell Firefox and Safari users that they are 'optimized for Chrome' when their sites failed.

What if your website, to borrow a phrase, just worked?

Consider delivering your content in plain HTML, and then 'mustard-cutting' to deliver your CSS and Javascript.

Internet Explorer refuses to die.

Internet Explorer market share is >12%. That's more than Firefox. That's more than Edge, Safari and Opera combined.

Internet Explorer fails to support hundreds of features that Chrome has implemented.

Progressive enhancement is how we build for an internet that is increasingly fractured.

Polyfills, autoprefixer, caniuse, modernizr; these are great things. Consider, though, simply delivering content that any client can access as a Minimum Viable Product.

A List Apart has a wonderful article with some recommendations on how to mustard cut for both CSS and Javascript.

What are you using your framework for?

Is it as a static site generator? Cool. Render on the server. Serving static HTML is waaaay faster.

Let's assume...

Let's assume you've got your fallbacks and polyfills in place. Let's assume SSR isn't an option. How do we make Vue, React and Angular accessible?

Accessibility in Angular

AngularJS 1.7 shipped with a module called ngAria which created hooks for some aria roles. Angular 2+ seems to not have anything similar. You're on your own!

Accessibility in React

React seems to be a lot more on top of accessibility. They even bother to mention it in their docs!

Aria attributes are supported in JSX (but note that they're lowercased instead of camelcased like most other attributes).

A few gotchas with React

JSX has a tendency to break semantics though, especially with lists and tables, so get familiar with s and <> syntax.

The `for` attribute, used with labels, is written as `htmlFor` in JSX

React A11y

react-a11y is a promising looking tool for warning about potential accessibility issues in your React components.

Accessibility in Vue

Vue doesn't have any accessibility documentation... yet.

Emily Mears has written a pretty great article about accessibility in Vue. The main challenges are held in common with React - updating meta, handling focus and implementing aria.

Vue is pretty great as a framework - it's easier to pick up and understand than other frameworks, it scales much more gracefully than React, and only updates the components that need re-rendering.

Controlling focus in client-side frameworks

All three frameworks aggressively re-render the DOM - that's kind of the point.

Be aware that changes to the URL, and rendering of the virtual DOM can wreak havoc on focus. Each framework has methods for mitigating this with programmatic focus control: refs in React; vue-focus in Vue; ngFocus in Angular. Make sure you're familiar with the appropriate technique.

Presentations - turning data into stories

Right now you're generating data. Your work for your final assignment is

  1. understand the data
  2. generate and compare solutions
  3. tell a story

Presentations - understanding the data

First, think about what kind of data you're looking at. Is it quantitative? If so, compare it to a) industry standard benchmarks, and b) the needs of the client. Is the pageload time >2 seconds? Does your gazeplot completely miss the big sales banner?

If it's qualitative, really listen to what people have told you (verbally or otherwise), and be careful not to project your own assumptions. Think about it individually and collectively - was something annoying, but only to one person? Was some UI element a little bit frustrating for every single user?

Don't forget, 'what worked' can be as important as 'what didn't'.

Presentations - solutions

Now that you've understood your data, it's time to generate some solutions.

Keep solutions specific and positive - 'don't use hamburger menus' isn't an action, it's a non-action.

The gold standard is 'elegance', which is just a fancy way of saying 'cheap, fast, easy and effective'.

Most solutions won't be elegant though. It's up to you to be mindful of how resource-heavy your solutions are - and how certain you are of their efficacy.

The more uncertain you are of a solution, the more you'll need to be prepared to present multiple options, and to speak to the pros and cons of each one.

Consider laying out your solutions in a chart graded for issue severity and actionability.

Presentations - telling a story

The point of all this is to give people something they can use. Data is boring. If your report puts them to sleep, they won't use it. Anecdotes are fun, but lack credibility. People won't use your report if they don't feel they can trust it.

Use enough data to build a credible story, but focus on appealing to the things that people really pay attention to.

Be funny. Be informal. Think of your report as having a beginning, middle, and end. Tell the story of the website, the testing, the results, and the solutions. And yes, even the data.

The best way to do this is to focus on people. Talk about yourself, the participants, the website's audience, the client. That's the only real way to help us all figure out why the data matters.