Thursday, November 17, 2011

ARIA autocomples implementation insight

Autocomple widget is a text field having associated list of options so the user is allowed to type value into text field or choose it from available options. Basically autocomplete is variety of combobox control and the user expects it behaving similarly to combobox, for example, keyboard shortcuts should work mostly the same way.

ARIA allows the author to create autocomplete widgets by putting aria-autocomplete attribute on element having role="textbox" or role="combobox" attributes. There are examples on the web, for instance, here or here.

Usually authors prefer to use HTML input control as a base of autocomplete widget because they get typing implementation for free. All they need is to implement autocomplete list, navigation through list options and support standard combobox shortcuts.

When the user navigates autocomplete list then he's able to start typing to adjust list of available options. From implementation point of view the author tends to keep DOM focus on text field. That makes sense because if he keeps it on option element or autocomplete list then he'd need to implement typing on his own. But what is perceived focus in this case? I'd say the focus is on currently traversed option but when the user starts typing then focus goes into text field and visa versa. It's quite similar to comboboxes: when the user navigates options then focus is on option, if the user dismiss popup then focus goes into combobox itself.

How does it look from AT perspective? When the user navigates through options then AT should announce where the user is. For that the author can manage the DOM focus by tabindex technique, use ARIA live regions or try something else. Tabindex technique is really great because it's mapped into accessibility focus concept. The focus concept exists in all AT APIs what makes it universal and all ATs support it very well. Whenever focus is changed it gets announced to the user. ARIA live regions technique is good too because it's supported well by modern ATs.

Reality is the author doesn't want to manage DOM focus because it means special support for typing and he doesn't want to use ARIA live regions because it's hacky, complicated and sort of weird. So we have something else in the end. ARIA provides one more technique called active descendant which is supposed to be mapped to accessible focus but not restricted to it. So this one looks like authors could rely on.

The author wants to keep DOM focus on text field so he sets aria-activedescendant attribute on autocomplete list element which points to currently traversed option. ARIA implementation guide states that aria-activedescendant attribute change results in accessible focus event on pointed descendant iff the container has DOM focus. Since DOM focus is on text field then there's no focus event. Author can't manage aria-activedescendant on text field since autocomplete popup can't be a child of text field due to markup restrictions and strictly speaking it shouldn't be required to be a logical child (aria-owns).  Actually the relation between autocomplete and autocomplete popup should be described by aria-controls attribute but ARIA spec doesn't allow to map aria-activedescendant changes into focus event for elements of this relation.

So what do we have? Some AT APIs (like IAccessible2) has a concept of active descendant and the author could hope that ATs are smart enough so they can pick up active descendant changes and announce them to the user. Reality is active descendant concept is well supported neither by browsers nor by ATs. Some AT APIs (like MSAA) doesn't have it. I'm not aware of other use cases of this concept so that makes me think that active-descendant is going to require special support from ATs. But ATs like focus, they don't want to support new techniques when there's working old one. Autocomple widgets are not special and user interaction can be described in focus terms. That's how Firefox awesome bar works.

What can we do? I think ARIA spec should be changed to extend rules of active-descendant mapping into accessible focus. The following proposition sounds reasonable with me. Allow ARIA menu, listbox and tree widgets controlled (aria-controls) by the widget having DOM focus to manage accessible focus by aria-activedescendant technique. For example:

  <input aria-autocomplete="list" aria-controls="autocomplelist">
  <ul role="listbox" id="autocompletelist" aria-activedescendant="option1">
    <li role="listitem" id="option1">first option</li>
    <li role="listitem" id="option2">second option</li>

In this case AT should report accessible focus on the first option when the text field has DOM focus.

No comments:

Post a Comment