- make it as easy as possible to use
- make it work without page reloads
- make it fast
- make it accessible to everyone
For the last, but not at all least, point we were lucky and very happy to have Artur Ortega on our team. Artur is not only a brilliant backend engineer but also a screenreader user himself. Without his endless testing and suggesting workarounds, this application would not have been possible.
To arrive at the application you can use today, we went through an intense prototyping and user testing phase with many different iterations. Some of those iterations are still in the converter as parts of our progressive enhancement concept and all of them are based on pretty much the same markup.
The right markup
fieldset. The select fields contain a selection of the 20 most common currencies to convert from and to. The input field is used to insert the amount of money to be converted from and the submit button is of course to send the data to the server where the actual conversion happens.
The first enhancement is done by replacing the submit button with another input field to contain the converted result. Doing the conversion in realtime has multiple upsides. Not only is it a very nice effect which is fun to use, but also it's a very handy accessibility feature. If we'd used Ajax to make the conversion, the resulting load times between selecting the currencies, entering the amount, and tabbing to the result field would render the application very hard to understand for users unable to see what's happening.
Extending existing YUI widgets
Real-time availability of data is also one of the secrets behind the accessible currency search, which the select fields are progressively enhanced to allow. We've implemented the YUI AutoComplete widget so that as you type it suggests currency types based on your input. To make this widget fully screenreader accessible, we had to extend the existing class with a few small features. Hopefully this will no longer be needed in future versions.
One of our extensions permits additional text in the label of the auto-complete field. Using DOM methods, an extra span is added to the label simply containing the info: "Use the cursor down key to get suggestions based on your search" so screenreader users realize this input field has additional functionality. To make this text invisible in the layout but still available to screenreaders, the element is positioned off-screen using:
This info text is read aloud by the screenreader every time the input field is updated, the text is then removed after the screenreader user enters form mode. At that time, the onfocus() method of the field is triggered, which removes the text.
onblur() (when the user leaves the field), the text is added again, so it can be read again the next time the user enters the field.
We enhanced the AutoComplete widget to work with a screenreader by updating the content of the field with the selected value from the list of suggestions. When a screenreader is operating in forms mode it ignores everything that's not a form element. Therefore, the whole AutoComplete drop-down, which is a list element, is invisible to it. The screenreader is able to "see" the content in the input field that is in the process of being updated by the current user.
The YUI AutoComplete widget does not have this capability by itself, but another little extension makes it possible. Every time the user navigates in the suggestions list using the up-arrow and down-arrow keys, the active item is written to the input field. Thus, this useful functionality becomes completely available to screenreader users as well.
Focus() on what's important
By default, the source order of the field elements should define the tab order. (Please don't use
tabindex - it just makes everything more complicated and inflexible.) Whenever the workflow needs to break out of this order,
focus() helps. When a user clicks on the button to select an historic exchange rate, the YUI Calendar widget shows up. This is simply done by showing a div that had been hidden before. By default this means nothing to a screenreader. To make the screenreader aware of this change, set
focus() on it. The same functionality is used in the currency select window. Setting
focus() to the next logical element (which is not in the natural tab order) makes applications like this more usable for screenreader users as well as for keyboard-only users and anyone who's discovered how much faster one can work without a mouse.
Although WAI ARIA is a brilliant technology which does awesome things, it has a clear downside. A lot of screenreader users don't yet use software that supports it. At the moment, WAI ARIA is a great way to progressively enhance already accessible applications to be even more usable when WAI ARIA is available. WAI ARIA is not yet an effective way to make inaccessible applications accessible.
As you can see in this example, it is possible to achieve accessibility without the use of WAI ARIA and, I think, whenever possible it should be done.
This screencast shows how Artur Ortega uses the converter with Jaws (and a very slow and understandable voice setting so we're able to understand it too):
Web Developer, Yahoo! London