eBay

Combobox

Select phone model item specifics

Introduction

An enhanced textbox that allows free text input, selection from a list, or a combination of both. Hence the name 'combobox'.

A combobox is a composite pattern containing a textbox, listbox and button.

A combobox may optionally have autocomplete behaviour.


Updates

  • Feb 22nd, 2016
    • Issue with Safari and Voiceover not announcing combobox options is now fixed.
  • May 13th, 2016
    • Developer Guide added

Working Example

You can take a look at the combobox pattern in action on our examples site.

You can get an idea of the required markup structure by viewing our bones project.


Best Practices

Each row in the list of options allows only a single action. It is not possible to have multiple actions per row, e.g. select, edit and delete.


Interaction Design

Keyboard

Combobox keyboard focus will appear to be in two places at the same time (the textbox and the listbox). In actual fact, keyboard focus always stays on the textbox. The aria-activedescendant property controls the pseudo-focus inside of the listbox.

With keyboard focus on the combobox, down arrow key will expand the listbox.

Alternatively, you may wish to auto-expand the listbox as soon as focus lands on the combobox. In this case, you may wish to exclude the button.

There is no strict requirement for the combobox button to be in the keyboard tabindex. This is because the listbox can be expanded using the down arrow key.

Up and down arrow keys navigate the list of options.

Pressing ENTER key on any option will set the combobox value and close the list of options.

Pressing ESC key will close the listbox if visible, otherwise clear the textbox value.

Screen Reader

The screen reader will announce the input as 'text edit', 'combobox' or words to those effect, depending on level of ARIA support.

When keyboard focus is on the textbox, screen reader should announce "n suggestions available. Use up and down arrow keys to navigate" - or words to those effect. Typically this instructional text is not provided by screen readers and so must be coded in page.

Mouse and Touch

Clicking or tapping the combobox button will toggle the listbox display.

Alternatively, you may wish to auto-expand the listbox when tapping inside the combobox input.

Clicking or tapping an option will fill the combobox with that value. For long forms, the list of options must close without triggering form submit.


Developer Guide

Combobox is a good example of progressive enhancement. Until JavaScript is loaded or initalised, the textbox operates as a regular textbox. For example, a user can still enter and submit a value using the plain old textbox. The ability to choose a value from a list of pre-defined options is considered the enhancement that will be available with JavaScript.

Textbox

We start with a label and textbox:

<span class="combobox" id="combobox-0">
  <label for="combobox_0-input">Game Console</label>
  <input id="combobox_0-input" name="console" type="text" placeholder="Playstation 4, Xbox One, etc."/>
  <!-- button goes here -->
  <!-- description goes here -->
  <!-- listbox goes here -->
</span>

We have added our elements inside of a .combobox wrapper element. This wrapper acts as our module root and hook for CSS & JavaScript.

Remember: the textbox does not yet have a role of combobox, it is added later with JavaScript.

A button, description and listbox elements will be appended to this wrapper. It is up to you whether you wish to render these elements server-side or client-side. There are pros and cons to both approaches, which we will discuss below.

Button

The button should immediately follow the textbox. This button allows mouse and touch users to expand the combobox.

<button type="button" disabled>Expand</button>

It is sometimes useful to render this button on the server to avoid a flash of content or layout issues. If rendered on the server, the button should be in a disabled state. This is because the button is useless without JavaScript. The button can be enabled after all client-side initialisation for the widget is complete.

Description

At the time of writing, screen readers don't do a good job of letting the user know how to interact with a combobox or how many options it contains. To solve this problem, we can add offscreen text.

<span id="combobox_0-description" class="clipped">Combobox has 6 options. Use up and down keys to navigate.</span>

It is strongly recommended to add this description element on the client-side, and only after we are sure the widget is fully functional.

Next, in order for the screen reader to announce this description, we must add an aria-describedby attribute to the combobox. Again, this should be added using JavaScript on the client-side.

<input id="combobox_0-input" name="console" type="text" placeholder="Playstation 4, Xbox One, etc." aria-describedby="combobox_0-description" />

Now the screen reader announces the description whenever focus lands on the combobox.

Live Region

If the number of options changes based on the value of the combobox (i.e. filtering occurs) this new information must be related to assistive technology. The description element can be converted to a live region in order to achieve this.

<span id="combobox_0-description" class="clipped" role="status" aria-live="polite">Combobox has 6 options. Use up and down keys to navigate.</span>

The new attributes are role=status and aria-live=polite.

Note: aria-live attribute is technically redundant here, because status role has an implicit aria-live setting of polite. We add it to double-up on our support for older browsers and AT that might not support the status role.

Listbox

After the description, we add the listbox of options. The listbox may render on the server or the client. Like the disabled button above, it is wise to put the listbox in a semantically hidden state if rendering on the server. To do so, use the aria-hidden state (or HTML5 hidden attribute).

<ul id="combobox_0-listbox" role="listbox" aria-hidden="true">
  <li role="option" id="nid-0">Playstation 3</li>
  <li role="option" id="nid-1">Playstation 4</li>
  <li role="option" id="nid-2">Xbox 360</li>
  <li role="option" id="nid-3">Xbox One</li>
  <li role="option" id="nid-4">Wii</li>
  <li role="option" id="nid-5">Wii U</li>
</ul>

Using JavaScript we now convert the textbox to a combobox, by adding role=combobox. We also create the properties and state that connect the combobox to the listbox:

<input id="combobox-0-input" name="console0" type="text" placeholder="Playstation 4, Xbox One, etc." role="combobox" aria-expanded="false" autocomplete="off" aria-owns="combobox_0-listbox" aria-describedby="combobox_0-instructions">

The new attributes are role, aria-expanded, autocomplete and aria-owns.

Keyboard Navigation

Our elements are now in place, but how does a keyboard user navigate to the options? We cannot use TAB key because focus must stay on the combobox (so that user can type characters). As with any widget, the answer lies in the arrow keys. Up and down arrow keys are the way to select our combobox options.

If focus must remain on the combobox, how then do we also have focus on the listbox options? The answer is that we don't. Focus always remains on the combobox and instead we have a kind of pseudo-focus on the options. We call the option with pseudo-focus the active descendant. And guess what? Yes, there is an ARIA attribute for this called aria-activedescendant. This attribute is placed on the combobox element. The attribute value is the ID of the currently active (pseudo-focussed) option.

To make all of this easier, we recommend using a plugin such as jquery-active-descendant. After your HTML structure is in place, simply activate the plugin on the widget and up/down arrow keys will update the necessary states. Use CSS to style the active descendant in any way you like.

JAWS Keyboard Navigation

At the time of writing we have found that role of combobox does not force JAWS into application mode. This means that ARROW keys will be intercepted by JAWS, thus making UP/DOWN arrow key navigation problematic. In order to force JAWS into application mode, we apply a wrapper element with role=application.

<span role="application">
  <span class="combobox" id="combobox-0">
    <!-- label, input, description, etc -->
  </span>
</span>

We hope that this workaround will only be a temporary measure until we see better support for combobox role in JAWS.

We expect to have this section finalised in 2016.

ARIA Reference

This section gives an overview of ARIA usage, within the context of this pattern.

role=application

We have found that this wrapper role is necessary for correct behaviour of keyboard accessibility in JAWS and IE.

role=combobox

This attribute changes the role of the text input from textbox to combobox. We recommend applying this attribute on the client-side with JavaScript.

role=status

This role converts the offscreen text description/instructions into an ARIA live region.

role=listbox

The list of suggestions has a role of listbox

role=option

Each listbox item has a role of option.

aria-describedby

This property connects the combobox to the offscreen description/instructions.

aria-owns

This property connects the combobox to the listbox.

aria-expanded

Conveys the expanded state of the combobox.

aria-label

Provides the expand/collapse button with an accessible label, in the case where it has no visible text (i.e. an icon button).

results matching ""

    No results matching ""