Closed terracoda closed 5 years ago
@jessegreenberg , @zepumph , @mbarlow12 I have coded up an HTML select
box. I have a feeling that might be way simpler than a custom combobox.
Please have a look in the html-sketches folder: combobox/combobox-examples.html
I am going to put the design notes here in the issue and remove them from the example html.
Here's the draft visual highlighting Functionally, both the Up and Down Arrow keys activate (pop-up) the collapased list of options. We may want to consider adjusting the visual prompt which only indicates the Up Arrow. Also in the visual, a selected item is not visually indicated. We may want to consider adding a visual checkmark (or some visual cue) to visually indicate which item is currently selected.
Combobox gains focus with the Tab key (or other method). I don't think we need the checkmark on the selected item when the combobox is collapsed.
Space key, Up Arrow, or Down Arrow open the list of solutes. The selected item has focus when the combobox is opened. A visual checkmark has been added for emphasis.
Focus highlight moves with Up and Down Arrow keys, and the selected item stays checked until a new selection is made by pressing the Enter key. Combobox closes when a new item is selected with the Enter key or Space key. Escape key also closes the list of options without making a change in selection.
Note: I updated key presses.
Example 1: HTML Design Pattern (working example)
The HTML design pattern uses the select
element with a solutes codes as option
elements. This works out-of-the-box with keyboard navigation and in Voice Over on Safari. The HTML size
attribute can be used to make a designated number of options persist visually; however, this is undesirable in this case, and likely for most of PhET's interactive sim elements of this type (i.e., pop-up menus/comboboxes).
<label for="solute-options">Solute:</label>
<select id="solute-options" name="select">
<option value="1">Drink mix</option>
<option value="2">Colbalt (II) nitrate</option>
<option value="3">Colbalt Chloride</option>
<option value="4">Potassium dichromate</option>
<option value="5">Gold (III) chloride</option>
<option value="6">Potassium chromate</option>
<option value="7">Nickel (II) chloride</option>
<option value="8">Copper sulfate</option>
<option value="9">Potassium permanganate</option>
<option value="10">Potassium dichromate</option>
</select>
Example 2: ARIA 1.0 Design Pattern (non-working example) The ARIA 1.1 design pattern is not yet supported. Both the 1.1 and 1.0 design patterns seem very complicated to me. And since our PDOM is visually hidden, I think the HTML solution in Example 1, above, is better for us.
In ARIA 1.1, therole=”combobox
” is now a composite widget, meaning that it supports child element roles including active element roles embedded within it. However, the design pattern is too new to use.
In the ARIA 1.0 design pattern example below, there are three attributes on the focusable HTML input element that has the role="combobox"
that have to be maintained dynamically.
These are:
aria-expanded
aria-controls
aria-activedescendant
(Also, this attribute might not be allowed on the input
element)I think in our case the widget is read-only, as it is not editable, but placing the HTML5 readonly
attribute on the input element removes the element from the Tab order. The code below is a non-working example. See Whatsock for a working example. This is the pattern I tried to follow.
<input id="solute-comboxbox" tabindex="0" aria-label="Solute" type="text"
role="combobox" aria-expanded="false" aria-autocomplete="list"
aria-controls="owned-solute-listbox" aria-activedescendent="" readonly>
<ul role="listbox" id="owned-solute-listbox">
<li role="option" id="solute-option-01">Drink mix</li>
<li role="option" id="solute-option-02">Colbalt (II) nitrate</li>
<li role="option" id="solute-option-03">Colbalt Chloride</li>
<li role="option" id="solute-option-04">Potassium dichromate</li>
<li role="option" id="solute-option-05">Gold (III) chloride</li>
<li role="option" id="solute-option-06">Potassium chromate</li>
<li role="option" id="solute-option-07">Nickel (II) chloride</li>
<li role="option" id="solute-option-08">Copper sulfate</li>
<li role="option" id="solute-option-09">Potassium permanganate</li>
<li role="option" id="solute-option-10">Potassium dichromate</li>
</ul>
Thanks for working on this @terracoda, looks great and nice mockups!
I think we ran into trouble with the <select>
box because we couldn't figure out how to hide the options in the parallel DOM. @zepumph am I remembering this correctly? @terracoda do you know of a way to make the select box drop down and options invisible with CSS?
If it can't be hidden, we might be stuck with an ARIA pattern.
The Whatsock example is working really nicely, I agree it is very complicated.
For me the Whatsock example does not read out the individual options in VO and Safari. I only hear the selected language.
Good to know @terracoda, thanks
@jessegreenberg can you explain what you mean by "hide the options in the PDOM".
@jessegreenberg, are you concerned about number 2? or something else? Number 2 seems natural to me, but might complicate implementation.
We might be able to restrict access to the options until the pop-up is actually open. I'd have to play with some things (hidden, aria-hidden, aria-expanded, css, etc). The size attribute doesn't seem to have any effect when set to 1.
I'll wait for @zepumph to comment with details because right now select
and option
seem to work beautifully for me out of the box.
The problem is that the HTML select box needs to be invisible for sighted users. The last time we tried to use select
, we couldn't figure out how to make the options box invisible. Take a look at this example:
https://jsfiddle.net/Lfbea747/show/
(You can see the HTML here: https://jsfiddle.net/Lfbea747)
Click in the grey box under 'Show' and press enter, and you will still see the box of options even though the select box is hidden. We couldn't figure out a way to hide this box with CSS, but there could certainly be a way we didn't think of. If we could use select
I agree that would be the most straight forward.
@jessegreenberg, I don't understand how jsfiddle is supposed to work, but does this work?
<div style="text-indent: -1000em;">
<label for="solute-options">Solute:</label>
<select id="solute-options" name="solute-options">
<option value="1">Drink mix</option>
<option value="2">Colbalt (II) nitrate</option>
<option value="3">Colbalt Chloride</option>
<option value="4">Potassium dichromate</option>
<option value="5">Gold (III) chloride</option>
<option value="6">Potassium chromate</option>
<option value="7">Nickel (II) chloride</option>
<option value="8">Copper sulfate</option>
<option value="9">Potassium permanganate</option>
<option value="10">Potassium dichromate</option>
</select>
</div>
I think we may need to look seriously at how we are hiding the PDOM. Ideally, the entire thing is hidden in the same way.
@jessegreenberg I see what you mean now. The grey box seems to return visually, eventhough everything is moved off screen.
This needs some investigation.
@terracoda I tried text-indent: -1000em;
, it works great in Chrome! But the box still shows up at the very left edge of the screen in Safari.
@jessegreenberg, yes, same with Safari. The position of the box is very persistent.
@jessegreenberg, it finally disappeared with an option focus style applied. I'm not sure how robust this is, but I do not see the list of options or anything else in Safari.
In the head...
<style>
.hide-me {
text-indent: -1000em;
}
option:focus{
display: block;
text-indent: -1000em;
}
</style>
And in the body...
<div class="hide-me">
<label for="solute-options">Solute:</label>
<select id="solute-options" name="solute-options" size="1">
<option value="1">Drink mix</option>
<option value="2">Colbalt (II) nitrate</option>
<option value="3">Colbalt Chloride</option>
<option value="4">Potassium dichromate</option>
<option value="5">Gold (III) chloride</option>
<option value="6">Potassium chromate</option>
<option value="7">Nickel (II) chloride</option>
<option value="8">Copper sulfate</option>
<option value="9">Potassium permanganate</option>
<option value="10">Potassium dichromate</option>
</select>
</div>
A negative left margin also seems to work.
For example:
<style>
.hide-me {
margin-left: -1000em;
}
option:focus{
display: block;
margin-left: -1000em;
}
</style>
Awesome, thanks @terracoda! Unfortunately I tried the above in a JSFidddle and it didn't work for us in Safari, the box of options kept appearing. Would you mind sending a JSFiddle with it working in case we didn't use the right CSS? Or we could do a voice chat and share screens some time.
@jessegreenberg, did you try the actual HTML file on github?
I just tried https://github.com/phetsims/a11y-research/blob/master/html-sketches/combobox/combobox-examples.html, I can see the box in Safari 10.0.1 when I open it with spacebar.
EDIT: it is hidden correctly in Chrome.
Oh, I seemed to have been incorrect. I get the pop-up in Safari 11.01, too.
Would this "detaching" method work in our situation? https://stackoverflow.com/questions/4398966/how-can-i-hide-select-options-with-javascript-cross-browser
@terracoda I think that solution with .detach()
is actually removing the elements from the DOM, not just hiding them. One thing I noticed was that the box looks different when the size attribute is used, and I am wondering if using size
will prevent a box from being shown visually. @terracoda do you know if the size attribute will have an impact on how AT interpret this element?
@jessegreenberg, I did test the size attribute. When I set it to 10, the box is always open and it looks different. I didn't try to move it off screen. There was no difference to AT that I noticed. I could check again.
@jessegreenberg, it stays off screen with size="10", and it does change the announcement a little in VO. Instead of the select being described as a pop-up button, it is described as a listbox. Arrow keys still navigation up and down and Enter changes active selection.
@jessegreenberg, when using the negative text-indent offscreen method, the select with size of 10 does take up vertical space, though it is not visible. Using a positioning technique might solve that issue.
@jessegreenberg, the default interaction for the listbox items has them autoselect. The selected item is announced upon focus. Navigating with Arrow keys autoselects item (without overt announcement). Typing the first letter of a solute jumps to that solute (e.g. G jumps to Gold). Tabbing away, "Leaving listbox" is announced, and then when returning to Listbox, the last item read out is read out as the selected item with it's place in the list(3 of 10).
@jessegreenberg , fn key and Up/Down Arrow go to first and last items.
@jessegreenberg, got it.
Here's the css
.hide-me {
position: relative;
}
.hide-me select,
.hide-me label {
position: absolute;
left: -999em;
}
Here's the HTML
<div class="hide-me">
<label for="solute-options">Solute:</label>
<select id="solute-options" name="solute-options" size="10">
<option value="1">Drink mix</option>
<option value="2">Cobalt (II) nitrate</option>
<option value="3">Cobalt Chloride</option>
<option value="4">Potassium dichromate</option>
<option value="5">Gold (III) chloride</option>
<option value="6">Potassium chromate</option>
<option value="7">Nickel (II) chloride</option>
<option value="8">Copper sulfate</option>
<option value="9">Potassium permanganate</option>
<option value="10">Potassium dichromate</option>
</select>
</div>
@jessegreenberg, brilliant idea about revisiting the size attribute.
Commit https://github.com/phetsims/a11y-research/commit/f27180782fa35ed441d91f2f31c065ee6a06359c makes changes in the sample html sketch for a combox.
@jessegreenberg, the listbox stays hidden, but still operable in Safari with VO. There are a couple of quirks with key presses (e.g., first down arrow key press is not read out) that we might need to look more deeply at.
This listbox thing, may still be easier than the ARIA 1.0 combobox.
Awesome, great work @terracoda I just verified that the box remains hidden in Safari 10.0.1!
One remaining question is how we will synchronize the select
with the styling of the ComboBox in sun.
HTML Events input
and change
don't fire until an option is selected with enter or spacebar. And the option element itself does not receive focus from the browser. So in order to update the display, we will have to listen for keydown
events and somehow detect changes to the select box to support the features @terracoda listed in
https://github.com/phetsims/a11y-research/issues/64#issuecomment-349978506
https://github.com/phetsims/a11y-research/issues/64#issuecomment-350336905
https://github.com/phetsims/a11y-research/issues/64#issuecomment-350341231
The next step will be to determine if we can detect keydown
on select
element when VO, JAWS, and NVDA are enabled, and if we can figure out which option is hovered.
Then we will need to figure out how to detect which option has the blue background when the box is open and we are navigating with arrow keys.
@mbarlow12 would you mind looking into https://github.com/phetsims/a11y-research/issues/64#issuecomment-350385303 in a JSFiddle or HTML page outside of a sim?
@jessegreenberg and @mbarlow12, there may be some flexibility in the interaction patterns for listbox that can be made similar to a select box.
I would suggest reading the design patterns for listbox and select and see where they are similar and/or different.
@terracoda is listbox an ARIA role or an HTML element?
@jessegreenberg great question. listbox
is an aria role, not an HTML element. However, some how when I added the size="10"
the select
element, it automatically took on the role of listbox. At least that is how it is described and how it seems to work in Voice Over in Safari.
Interesting, thanks.
At least that is how it is described and how it seems to work in Voice Over in Safari.
Is this OK, and do you think it sounds good enough in VO to continue using select
?
@jessegreenberg and @zepumph, I am going to read over the keyboard design pattern for the listbox
and see how it intersects with the native select
element pattern. The first obvious difference is listbox items autoselect, but that might be optional.
I have added code example for listbox from MDN. I have not been able to successfully label it, and it currently is not dynamic. Regardless, it seems like a potential option for us.
<div id="label-listbox1">Solute 3</div>
<div role="listbox" tabindex="0" id="listbox1" onclick="return listItemClick(event);"
onkeydown="return listItemKeyEvent(event);" onkeypress="return listItemKeyEvent(event);"
onfocus="this.className='focus';" onblur="this.className='blur';" aria-activedescendant="listbox1-2" aria-labelledby="label-listbox1">
<div role="option" id="listbox1-1">Drink mix</div>
<div role="option" id="listbox1-2" class="selected" aria-selected="true">Cobalt (II) nitrate</div>
<div role="option" id="listbox1-3">Cobalt Chloride</div>
<div role="option" id="listbox1-4">Potassium dichromate</div>
<div role="option" id="listbox1-5">Gold (III) chloride</div>
<div role="option" id="listbox1-6">Potassium chromate</div>
<div role="option" id="listbox1-7">Nickel (II) chloride</div>
<div role="option" id="listbox1-8">Copper sulfate</div>
<div role="option" id="listbox1-9">Potassium permanganate</div>
<div role="option" id="listbox1-10">Potassium dichromate</div>
</div>
Using a list instead of divs does not seem to change any semantics in Voice Over.
Added the code example with un-ordered list code. Key presses not fully implemented. This would require a developer's help.
<h3 id="label-listbox4">Solute 4</h3>
<ul role="listbox" tabindex="0" id="listbox4" onclick="return listItemClick(event);"
onkeydown="return listItemKeyEvent(event);" onkeypress="return listItemKeyEvent(event);"
onfocus="this.className='focus';" onblur="this.className='blur';" aria-activedescendant="listbox4-4" aria-labelledby="label-listbox4" style="list-style:none;">
<li role="option" id="listbox4-1">Drink mix</li>
<li role="option" id="listbox4-2">Cobalt (II) nitrate</li>
<li role="option" id="listbox4-3">Cobalt Chloride</li>
<li role="option" id="listbox4-4" class="selected" aria-selected="true">Potassium dichromate</li>
<li role="option" id="listbox4-5">Gold (III) chloride</li>
<li role="option" id="listbox4-6">Potassium chromate</li>
<li role="option" id="listbox4-7">Nickel (II) chloride</li>
<li role="option" id="listbox4-8">Copper sulfate</li>
<li role="option" id="listbox4-9">Potassium permanganate</li>
<li role="option" id="listbox4-10">Potassium dichromate</li>
</ul>
@jessegreenberg, sorry missed comment https://github.com/phetsims/a11y-research/issues/64#issuecomment-350400941
Re your question:
Is this OK, and do you think it sounds good enough in VO to continue using select?
So far, the select with size attribute (i.e. select/listbox) sounds better than the other listbox examples I have added to the mock-up. I thought is was worth exploring a couple of code options to test in different environments. The biggest issue with the select/listbox seems to be the hiding of the actual options box. If that is resolved, and if it sounds good on all platforms, then I think it is our best option, thus far.
Two things I think we should consider:
listbox
that is not part of a select
element may be easier to hide.I added example 4 which adds a listbox
with a list structure to the mock-up.
@jessegreenberg, do think it is worth trying to program in a listbox interaction that does not move selection with focus to see what it sounds like in different AT?
My examples do not have the full keyboard interactions built in.
How the default Select box interaction works in Safari:
I think it is within the ARIA Best Practices to make either a Select/listbox or an ARIA listbox behave like the above Select box interaction.
Do people think that is reasonable way to go?
@jessegreenberg and @zepumph I showed and explained Example 1 (hidden) and Example 4 to @emily-phet and she thought it was worth implementing the Example 1 (hidden) and Example 4 in Molarity with the Select element interaction pattern to see which code works best across Browser and AT combos.
Great, thanks for collecting this list @terracoda, that is really helpful. Also great to see a listbox example. So I think our priority of investigation should be to:
@mbarlow12 would you be able to investigate the first bullet point? We can pair on this the next time you are available if you like.
Gathering resources for combobox: