Combobox - trussworks/accessibility GitHub Wiki

Use a combobox when you want to allow the user to select from a list of many options.

This is specifically for cases where <input type=’checkbox’ />, <input type=’radio’ />, or <select> are not enough. One way you know you have reached the limitation of these other elements is when navigating the list of options is difficult because there are too many items in the list, or the items are structured in such a way that it will be challenging to select items on the list without excessive scrolling or keyboard navigation.

At its most basic, role="combobox" is used for a composite widget. It includes a text input used in combination with an associated popup that helps a user set the text input value. The popup can display the options in any number of ways. The available accessible roles for the popover element include listbox, grid, tree, dialog.

The expected behavior for a combobox is directly related to which implementation is used. A popover that is a simple list may be interacted with differently than a grid. The same can be said for a combobox that has filtering or autocomplete and one that doesn't. Consider this as you write your accessibility requirements.

Common use cases for combobox on Truss projects:

A multiselect

image4

A single select that is filterable or includes autocomplete

image5

A search textbox that auto populates results in a popover (rather than a list or table on the page), usually to save on screen real estate.

image1

Requirements for a Combobox with a list

Expanding the list

The combobox popover can be expanded by hitting the ‘Down’ key, or by pressing ‘Enter’. When the popup associated with a combobox opens, the focus should generally be set to the first element in the popover.

Closing the list

The combobox should contain a visible button element that will close the popover, such as an ‘X’. The combobox popover is closed by clicking the ‘X’ element, tabbing to focus the ‘X’ element with the keyboard and hitting ‘Enter'. The list can also be closed by hitting the ‘Escape’ key at any time. After the popover closes, the text input should be focused.

Navigating the list

  • List items can be selected by click or by pressing ‘Enter’ or ‘Tab’. If the user tries to select an item that is already selected, that entry will be unselected.
  • List items that are already selected must have a visual cue and be called out in the screen reader. They should stand out in the list.
  • List items that have focus and should be highlighted visually and in screen reader as well. That means there are at least two types of cue in the popover list, both “this item is currently selected” and “this item is active”.
  • List items can be navigated through by scrolling or by using the up and down arrow keys.
  • If using a multi-select, selected items should be focusable using the left and right arrows. Backspace should remove selected items from the list.

Search or filtering

Note: Adding filtering makes this component much more complex. Make sure you test your filtering with users, including cases where no items are found.

  • If the number of items in your list can change, make sure there is a way to find the total remaining count of the list by screenreader
  • If the number of items in the list could be zero, with no items remaining, make sure that is announced
  • When you have a list that may change dynamically (due to search or filtering), you may have to do some extra JS work to manually reset focus.
    • For example, if there are no items in the list, what should be focused?
    • Or, if the user is in the middle of navigating the list, what happens if they then start typing in the search box and then return to arrow down in the list?
    • Make sure your QA efforts around filtering include keyboard only testing.

Important Markup

On the element container

role=combobox should be placed on the element wrapping the text box and popover together.

aria-owns should be placed on the textbox input, assigned to the id of the popover.

aria-expanded should be set on the textbox or the combobox element wrapping the textbox and popover together. This attribute tells user agents that there is an associated element (the popover) which may be open or closed.

On the textbox input

aria-controls should be placed on the textbox input, assigned to the id of the popover. This attribute is mainly for JAWS, it helps signify that there is a popover element with suggested values for the input.

On the popover

A clear role on the popover element. This can be a role listbox, tree, grid or dialog.

Depending on the usage of the combobox you may also have aria attributes like aria-autocomplete, aria-readonly aria-required etc.

QA example script

The following example checklist could be used during development or QA.

The combobox text input must:

  • Inform the user the purpose of the input via properly associating a label
  • Receive focus when tabbed into
  • Inform the user how to open or search for options
  • Inform user what is currently selected
  • Inform user how to remove currently selected items
  • Can be closed using ‘Escape’ or tabbing to ‘X’
  • Allows text input if setup as a typeahead or search/filter input
  • Inform user visually which items are selected
  • Inform the user on number of selected items when focusing a populated combo box with one or more items selected

The combobox popover must:

  • Receive focus on first element in list by default
  • inform user visually which item is selected
  • Inform user visually which item is focused
  • Inform user by screenreader of the number of possible items
  • Allow scrolling to navigate list while popover is open
  • Allow for arrow keys to navigate list
  • Allow for ENTER or TAB to select currently highlighted option
  • Be possible to close by keyboard only (ESC key)
  • Return focus to textbox when closed

How to evaluate a third party combobox

  • Make sure the third party library is actively supported. HTML spec and accessibility requirements continue to mature, its important a library is supported
  • Pull into a code sandbox or storybook and check keyboard support following the QA example script
  • Confirm that your designs can either be adapted to use the third party UI OR there is the ability to customize the styles needed.
    • A common issue with custom styling third party combobox elements is that customization may only be allowed for certain levels of the HTML markup — e.g. just the textbox or just the popover or just elements (such as a pill or capsule UI) within the popover.

### Projects at Truss that have used accessible combobox

MC-Review - uses react-select for a combobox behavior React-uswds - has combobox

Further Reading

WAI-ARIA Authoring Practices 1.1: Combobox See also: Examples of listbox popover within a combobox from WAI-ARAI for detailed discussion of keyboard support.

USWDS combobox component This is an example of a combobox that also has a screenreader-only select element above it in the DOM to mock similar behavior.

Sarah Highley has two interesting long form articles called "select your poison" The articles also have associated github repos with example code and keyboard interaction guidelines as well. For example, see the multiselect combobox example.

Code Example

<label for="ex1-input"
       id="ex1-label"
       class="combobox-label">
  Choice 1 Fruit or Vegetable
</label>
<div class="combobox-wrapper">
  <div role="combobox"
       aria-expanded="false"
       aria-owns="ex1-listbox"
       aria-haspopup="listbox"
       id="ex1-combobox">
    <input type="text"
           aria-autocomplete="list"
           aria-controls="ex1-listbox"
           id="ex1-input">
  </div>
  <ul aria-labelledby="ex1-label"
      role="listbox"
      id="ex1-listbox"
      class="listbox hidden">
  </ul>
</div>
⚠️ **GitHub.com Fallback** ⚠️