Cyberpks
Cyberpks

Reputation: 1421

Adding role="listitem" out of role="listbox"

While working on updating a webpage, I have a control that is basically a multiselect control, looks like the below image.

enter image description here

Once the user sets focus on the textbox (the one with purple border, the box below gets visible, wherein on check of the items, the same gets appended to the above text box.

Question:

My question is more from the Accessibility perspective. To allow assistive technologies to read (narrator) this control properly. I am using role="listbox" to the text box and role='listitem' to each of the checkboxes, which I understand it wrong way since listitem should be added as direct child to listbox. But in my case it is not possible.

Is there any way I can link up the textbox and checkbox list and make narrator to treat them as a single control?

<div class='multiselect_wrapper'>
     <input type="text" role='listbox' aria-multiselecttable='true' />
     <div class="chkList">
           <fieldset>
                <div>
                    <label role="listitem" for='chk1'>
                          <input type='checkbox' id='chk1'>Pizza
                    </label>
                    <label role="listitem" for='chk2'>
                          <input type='checkbox' id='chk2'>Lemonade
                    </label>
                    <label role="listitem" for='chk3'>
                          <input type='checkbox' id='chk3'>Fruit Salad
                    </label>
                </div>
           </fieldset>
     </div>
</div>

Upvotes: 0

Views: 1198

Answers (1)

QuentinC
QuentinC

Reputation: 14772

Here's a quick example of a very simple checkbox list:

codepen .io /anon/pen/eboEVB

This is just a quite incomplete example. Do inspire from it, but don't copy-paste it as is.

A few points of attention:

  • As you have effectively mentionned, the items having role=listitem must be child of the element with role=listbox. This is an obligation, meaning that you have no choice but leave the textbox apar if you want to have correct and accessible code.
  • If you set role=listitem to the checkboxes, it will override the default implicit role=checkbox. The consequence are that the screen reader won't see them as checkboxes anymore, and thus will keep reading their labels but no longer their state (checked or unchecked). You must set the role=listitem to another element for which there is no default implicit role, such as the divs used in the example
  • Note how the focus is given to checkboxes rather than to listitems. In this way, we obtain for free normal keyboard processing (i.e. spacebar toggles), as well as the default behavior screen reader have with checkboxes (i.e. announce label and state + help like "press spacebar to change state")
  • You are recommanded to set the attributes aria-posinset and aria-size to each item, otherwise the screen reader might not see your listbox as such
  • Set tabindex=-1 in all the items except the currently selected one, which must have tabindex=0. Usually in listboxes, the keyboard user don't tab on each item, and use arrow keys to go from one item to another once they are in the list box. The example is incomplete, it would be nice to support home, end, page up and page down as well.
  • Don't forget to keep the aria-descendant attribute of the listbox in sync with selection changes. This is important because screen readers use it to tell which item is currently selected

Edit: I'm unable to post my HTML+js code, please help! I'm trying to post a link to codepen but it is refused. The code is quite long but anyway, if I post it indented with 4 spaces (using Ctrl+K), it is still interpreted instead of just be shown.

Upvotes: 1

Related Questions