Finding the best "perfect"

Or, as submitted...

Roads Less Traveled:
When to Detour from Standards to Reach Accessible UX

Presented at CSUN 2019

By Scott O'Hara of The Paciello Group (TPG)

Accessibility and inclusive UX can be hard...

Captain Obvoius, from commercials, knowingly putting his finger to his face. (thank you captain obvious)
Notes: a11y and inclusive UX can be hard

Not just within the scope of auditing, writing criteria for new accessible features.

But specifically when you have to convince designers, developers, and stakeholders to make it a priority.

Getting buy in can be hard. It can be harder when you get buy in, and then you follow criteria, specifications, best practices, and things don't work out as expected.

Trivia Time!

Unexpected stage setting...

Trivia Time!

<img src="logo.svg" role="img" alt="...">

Without role=img VoiceOver on...

  • macOS announces as the <img> as a "group"
  • and iOS will ignore it entirely

bug filed

Trivia Time!

native buttons showing off their colors in windows high contrast mode. white for normal, and aria-disabled. green for button with disabled attribute (respecting WHCM setting)

Windows High Contrast Mode cares not for your ARIA

More info on Windows High Contrast Mode styling

Trivia Time!

Safari and Chrome on macOS currently need:

<footer role="contentinfo">

<address role="presentation">

bug filed (fixed) and bug filed (open), respectively

Notes: contentinfo

Largely through browser implementation, and partially through screen readers propping up IE, landmarks have great support. But Webkit has open issues for correctly exposing contentinfo.

Trivia Time!

Firefox Android presently lacks support for
aria-describedby (at least with form fields, needs more testing).

<input aria-describedby="desc"><p id="desc">Ignored!</p>

bug filed (fix will release in Firefox 67).

Just one more question:

Where am I going with this?

Notes: one more question

It's not enough to point to best practices, if those best practices currently have gaps in implementation, have only a passable user experience, or result in avoidable assistive technology quirks.

Technology and user expectations change rapidly. We should always test to ensure not only emerging patterns work correctly, but tried and true patterns continue to work as we expect.

If a road is closed, find another way

Notes: road closed

There is never not another option. Whether it's a design change, or deviating from generally accepted best practices.

If we can figure out a way over, around or even barreling through that gap. Let's take it. (Note: I'm not advocating for hacks that would create significant tech debt, or create a poor experience for when a bug is fixed. Rather I mean we should implement 'silent' work arounds that would have no impact were a bug to be rectified. Or implement a separate pattern/design that wouldn't cause an issue and possibly could have better UX anyway.)

HTML Design Principles WD:
3.2 - Priority of constituencies

"In case of conflict, consider users over authors over implementors over specifiers over theoretical purity."
Notes: Priority of constituencies

We need specs, guidance, and shouldn't take for granted the countless hours and hard work that people put into create documents.

But, if there's a gap in implementation, or something doesn't quite make sense or meet users' needs...

We can't just shrug and say "out of our hands."

Searching for
alternate paths:

  • When expectations don't match reality.
  • When there are no clear expectations.
  • When expectations went out the window.

When expectations don't match reality: role="switch"

Background image: McKayla Maroney is not presently impressed with role="switch".

Is it a good switch or a bad switch?

What are the issues?

  • iOS: role="switch" announces as checkbox & doesn't announce state.
  • Firefox and Chrome with NVDA announce as a "toggle button".
  • NVDA will always announce "not pressed" regardless of state.
    (e.g. "not pressed, checked") - bug filed.
  • IE11 with screen readers sort of a mix of all the above.

Which switch is switch?

Checkbox switch Toggle Button Switch

When there are no clear expectations: carousels

Is this what user delight looks like? animated gif of a young girl holding onto a merry-go-round with a single hand. She is laying face down on the floor and the merry-go-round is dragging her along the floor as it spins, slowly, in an infinite animated gif loop.

should I use a

Credit: Jared Smith

But sometimes saying "no" doesn't work...

Carousel Criteria:

  • Progressively Enhanced markup.
  • Have slides with a single call to action.
    • Possibly with optional short description.
    • But should not contain multiple accessible elements.
  • Strive for UX Equality & considerations:
    • Only active slide is accessible.
    • Slide purpose & current number is announced.
    • All users activate the CTA similarly.
    • Keep in mind high contrast & reduced motion media queries
Notes: carousel criteria

The issue with defining something like this, is that the best UX may be dependent on the contents:

For instance:

  • Content-heavy single panel carousels
  • Single call to action CTA / panel carousels
  • Carousels with multi-panels and ctas shown at a time

These may all require different types of UX to make a carousel accessible. Not to mention various different 'add-on features', such as auto-playing, which could potentially diminish the experience for different users.

I have found luck with a single-focus CTA carousel, in projects I've had to write criteria for carousels. Simple UX and functionality created more equivalent and better general UX for all.

Note: a few days before giving this talk I became aware that ARIA authoring practices have released a carousel and they are presently looking for feedback. I would recommend we check it out and provide any helpful feedback we can.

The Markup

<div role="group" aria-label="Name it!"

  <!-- visually hidden -->
  <span aria-live="polite"></span>

  <!-- role=presentation added by JS  -->
  <ul role="presentation">
    <li role="presentation">
      <div class="panel-bg">
        <!-- img here -->
      <a href="...">
        <!-- CTA text here -->

  <!-- generated by the JS -->
  <div class="pn-btn-wrap">
    <button>Previous slide</button>
    <button>Next slide</button>
    <p aria-hidden="true">X / Y</p>

read about aria-roledescription.

Single Call to action carousel (demo)

Note: looping has been disabled in this example.

But, I still don't recommend carousels...

repeat of animated gif animated gif of a young girl holding onto a merry-go-round with a single hand. She is laying face down on the floor and the merry-go-round is dragging her along the floor as it spins, slowly, in an infinite animated gif loop.

When expectations went out the (modal) window

two cartoon character modal dialogs are looking at each other. the one on the left says to the one on the right 'umm... your document is showing...'  the modal dialog on the right has a document (piece of paper) sticking out from behind its back. it looks embarrassed.

What is a modal dialog:

Dialogs are most often used to prompt the user to enter or respond to information. A dialog that is designed to interrupt workflow is usually modal. - ARIA 1.1
GitHub modal github modal with heading, warning text, and paragraphs of content prior to auto-focused text input and disabled by default submit button
CNN modal cnn modal showcasing an add about ruth bader ginsburg, and promoting their podcast on varoius platforms.
Sign in tab widget modala modl containing a tab widget that would allow someone to sign in, register, and 'why?' to the website. the inital focus moving past the tabs and focusing the alias text field modalMedium's modal pompting sign in via social account, or link, with decorative graphics and explanatory content after the sign in links and buttons
Reddit modalreddit modal dialog promoting their new profile feature. contains intro heading, text, a series of images and descriptions in a horizontal list format and a 'show me' button and customize your profile link(?)
"traditional" modala 'standard' alert dialog indicating that a request couldn't be completed. a heading, short text paragraph and ok button are displayed.
WordPress media manager modal wordpress's media manager modal dialog containing varoius buttons and form fields to provide alt text and other meta information to an image. Image currently being edited is of Will Ferrell as the character he played in Elf, yelling.

High level modal functionality

  • Creates a sub-window within the primary window.
  • Should contain a button to close.
    • expectations that Esc and
    • tapping/clicking outside will also close.
  • Should have an accessible name.
  • Should receive and manage focus when invoked.
  • Should not allow access to content beneath the dialog.
high level notes

"Should" does not mean "must". "Should" is often encouraged, and typically the most desirable expectation. However, "should" also implies that authors "could" take another path if necessary.

So what are the problems?

we use too many damn modals. let's just not.
- Adrian Egger,


We can't rely on the <dialog> element

  • Blink-based browsers only.
  • Inconsistent accessibility & bugs.
  • Polyfill doesn't make it fully accessible.



  • Added to ARIA in 2014.
  • Bugged with VO prior to Safari 12
    (fixed in Safari 12 - 09/2018)
  • Support still varies regarding platform.
    Tabbing and swiping will still often escape the dialog.

A solution:
inert & aria-hidden

<div role="dialog" aria-labelledby="aName">
  <div role="document"> <!-- but why? -->
    <h1 id="aName">...</h1>
    <!-- STUFF! -->
<div id="app" aria-hidden="true" inert="true">
  <!-- base document stuff! -->

inert polyfill

Note on role=document

The role=document was added to the code example to mitigate an issue with VoiceOver quick nav mode.

The issue here being that if a modal dialog has an accessible name, and the contents of the dialog are not wrapped in a role=document, then certain elements within the dialog may be inaccessible when quick nav is on.

This issue does not appear to exist if the dialog does not have an accessible name. Nor does it appear to exist if not using quick nav.


Initial focus placement is... opinionated...

diagram of initial focus placement comparison between a web document and a dialog. A web document, on the left, sets focus to the top of the document on page load.  A dialog have multiple arrows pointing to various different places of where focus could go based on content or other conditionals.
Notes on focus placement

For documents we start at the top

For modals, guidance and implemented native functionality may dictate that focus could go wherever the first focusable element exists, unless it is not in the visible viewport in which case another element must be focused.

There are various quirks in behavior, depending on the screen reader and browser used, when elements within a dialog have been focused.

I've written quite a bit about these in my article on native dialogs, and the current state of modal dialog accessibility (linked in references at the end of these slides)

Solution: focus what makes sense

HTML Design Principles WD:
4.2 - Avoid Needless Complexity

"Simple solutions are preferred to complex ones, when possible. ..."

WHATWG HTML Living Standard - dialog focusing steps

- GitHub thread advocating for change (which would then match HTML 5.3 draft's dialog focus algorithm).

Whatever your choice, .focus() on testing!

Regardless of where you set focus,
test to ensure the best user experience!

Note on testing

If you've found that your methods for implementing dialogs, focusing them, etc. meet the expectations of your users, then keep doing what you're doing!

Consistency of expectations and meeting the goals of our end users is our priority!

Wrapping up: some take aways

  • Don't assume, always be testing.
  • Validate features and implementation methods
    aka: Do your users need what you want?
  • We can help make the web better:
    • Find a bug, report it!
    • Displeased with guidance? Start a discussion!
Notes on wrapping up

We should remember we're far better off today than we used to be, regarding browser implementations, user experience, etc.

But there are inconsistencies and challenges that we still need to address.

And educate!

Not just the hows and whys of accessibility.

But educate about imperfections, how to test, and strive for UX equality above all else.

So let's just keep striving for the best perfect we can.

Animated gif: stop talking stop talking

Thank you


Additional reading

Quite a bit of this talk is based on testing and writing I've done over the past year or so. Here are some links to those posts:

Links to references and resources

Links to bugs and issues

For a list of bug trackers (and a generally awesome article) see Semantics to Screen Readers.