Nine months ago I gave a presentation with the same title as this blog post at Wicked Good Ember in Boston. You could watch last year’s presentation but my experiences since then have given me new perspectives and helped me distill my thoughts. At the end of my presentation, my conclusion and challenge was this:
As designers of rich web-based experiences we have largely abdicated our responsibility of participating in the design questions about the experience of our applications using assistive technology. We have spent two decades letting others design what that experience should be by reverse-engineering our code.
This consistent behavior makes for a good baseline–design patterns exist for a reason. However, we must now emulate that behavior as we move forward toward a more interactive future. We can’t change twenty years of design patterns overnight. But we can do better. We will do better.
And we can start by actually taking a seat at the table and designing experiences for users of assistive technology. In a decade of hard work maybe we’ll have something we can all be proud of to show for our efforts, and a new set of problems to solve.
Goal
My goal is simple: make Ember accessible by default. Well, at least simple to describe.
We, along with most client-side frameworks, have broken the web for users of assistive tech and we collectively need to reverse course and provide hooks and constructs that make it more difficult to be inaccessible than it is to be accessible. This follows with Ember’s principle of making the right way to do something easy and the wrong way hard. A rising tide lifts all boats and Ember’s convention over configuration gives us the leverage we need to make it happen.
Nothing about my goal has changed; and I believe that this a goal shared by the entire Ember community. However, each goal comes with multiple strategies to achieve that goal which is how most of our human conflict arises.
Naïveté
No plan of operations extends with certainty beyond the first encounter with the enemy’s main strength. – Helmuth von Moltke the Elder
I started this process by opening an RFC for Ember to add a bit of functionality to the core. I argued loquaciously for including this behavior and would take no prisoners in my advance toward that goal. I rapidly addressed all of the concerns that I could identify, categorized the remaining issues as irrelevant, and tried to push this through. Differing strategies were presented, different problems with each strategy were explored, and my proposed solution sat in limbo for nine months.
Through all of this the conversation was constructive, even if we disagreed with each other. All conflict on this issue wasn’t with the principle of the approach but instead the strategy which I was promoting.
Implementation
Strategy is a system of expedients. – Helmuth von Moltke the Elder
Unlike von Moltke, I’d failed to prepare myself for this conversation by not having multiple strategies to accomplish the same goal and being unwilling to compromise my position. This meant that once that path was exhausted I didn’t have a fallback option. Comments like Ed Faulkner’s which I vehemently disagreed with turned out to be remarkably prescient as the screen reader behaviors that the original solution relied upon have since changed.
So, eventually, I came up with a solution that would work as an addon, which, amusingly, leverages the same get-outlet-state helper that Ed wrote to support liquid-fire. (I really love the symmetry there.) This past weekend at the Zesty Hack Day I focused on bringing that home with Ben Holmes’ help, and now we have ember-a11y.
Next Steps
Since ember-a11y is decoupled from Ember’s release cycle we’re far better set up to deal with the inevitable massaging required to make things play nicely with the rapidly changing browser and assistive tech landscape. Also, we’ll be able to add additional features to achieve our goal of making Ember accessible by default. We can use this as a proving ground and as we identify mature techniques we can port them into Ember core with evidence as to their usefulness.
While we’ve managed to build something that sets focus to the correct portion of the page to provide the most optimal user experience, we’ve discovered that it doesn’t trigger the behavior we want in all browser and screen reader combinations. Our desired behavior:
- Set the assistive tech cursor focus to the newly populated area of the page (a div).
- Begin reading that entire section of content.
- Allow for navigation “into” that section of content as the “next” action.
So, this is only the beginning of the conversation, and you can help! You can try it out here and let me know if you have thoughts on how we can achieve this experience in each of the browser/screen reader/device combinations!