Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

select: clarifying what should be used as the chosen value #1117

Open
scottaohara opened this issue Oct 24, 2024 · 12 comments
Open

select: clarifying what should be used as the chosen value #1117

scottaohara opened this issue Oct 24, 2024 · 12 comments
Labels
agenda+ Use this label if you'd like the topic to be added to the meeting agenda select These are issues that relate to the select component

Comments

@scottaohara
Copy link
Collaborator

We have been talking about what the expected value / a11y exposure of the value should be if someone changes what is displayed in an option / what the accName is of an option vs what gets rendered in the selectedoption element.

There are also questions about what happens if one were to add things like aria-label to the button or selectedoption parts of the select, or adding extra content to the button part, outside of the selectedoption. Since authors might expect to be able to modify those element and have the announced value change.

To illustrate, consider the following:

https://codepen.io/scottohara/pen/mdNqxwE

<label for=s>example</label>
<select id=s>
  <button aria-label=test1>
    Extra text
    <selectedoption aria-label="test2"></selectedoption>
  </button>
  <option aria-label="tire fire">
    <svg aria-hidden=true class="tire-fire-icon"></svg>
    <div>if it burns <a href="#">go here!</a></div>
  </option>
</select>

<style>
select,
::picker(select) { appearance: base-select; }
option div { display: none; }
... /* more styles in the linked codepen */
</style>

Per the above, checking the chrome implementation (oct 24th 2024) the aria-label becomes the returned value for the select - in this case, "tire fire". From an initial a11y pov, this makes sense because when interacting with the option, this was the accName the user would have heard and what the option visually presents in the popup picker.

But there is "extra text" that is visible in the button part.

The selectedoption and the button parts each have aria-labels.

The actual text that's returned "if it burns go here!" is display none in the option that appears in the popup, but the "author" made it visible in the rendered value to collapsed select (oh and "they" added a link too.... perfect, that will be keyboard focusable, but not announced at all).

None of this is exposed in the select's collapsed state, because the name of the select is "example", the value is "tire fire" and all this extra stuff? well, up until now, no valid implementation of a select or role=combobox would have allowed for these things. There is no value computation algorithm to account for these things, and there is honestly also an argument to be made that this sort of stuff should probably be not supported at all.

This issue is to hopefully start a conversation on what to do about these things, lest it just be me soap boxing, though i know you all love that so much.

@scottaohara
Copy link
Collaborator Author

scottaohara commented Oct 24, 2024

So with that initial post out of the way, I of course have thoughts: (though i make no claim to how good they are):

  1. selectedoption (or whatever it will be named) should arguably be treated like the slot element, in that it should be made very clear to authors that, even though global html attributes can be set on it - because 'global' - none of those should be expected to work if the element is used within a select > button. Similar with ARIA attributes. I've been thinking about this a lot due to the conversation with happening in Addition: selectedoption element w3c/aria#2344

  2. There needs to be clear author expectations for the use of the "button" within a select as well. I'm starting to wonder if it's really necessary to even have that button, just like it didn't end up being necessary to have the datalist to contain the options.

    But if that can't be changed at this point, then there probably needs to be very clear expectations set that this instance of a button should not be considered the same as if someone was using a button outside of a select. Since, the button isn't even really used in the a11y tree. being a child of the combobox or popup button parent (the select element), it's more of a styling element than an actual "button". People shouldn't expect to put HTML button attributes or ARIA attributes on that and expect anything meaningful to happen. At least, that's what i think about this right now - lest a rather significant change be made to how this is exposed to the a11y tree.

  3. Again, on the topic of the button, adding text/other content within the button seems like it will be a footgun. I recall that some of the rational there was that people wanted to be able to maybe add their own chevron to the button part and use an actual SVG for that. Or adding text like "choose:" before the selectedoption being essentially throwaway text, since it will be ignored. But, as anyone can put anything into that button part - do we anticipate that? with the talk of videos, iframes, etc., those could get put into the button part - if not just the selectedoption due to their allowance in options?

  4. We probably need to define a value computation algorithm. ARIA has a plan to do this for custom ARIA elements like combobox, but it seems now there's a need for select since the value can be calculated from things that aren't even defined in HTML (e.g., aria-label).

  5. the visible value returned to the selectedoption (not necessarily content outside of the selectedoption) probably should be what the value is exposed as. I think it's really weird that if a user chooses an option in the popup, the returned value could be displayed as / announced as something else entirely - but, if someone's going to do that, all users should arguably get that weird experience, and not have a difference between what you see vs what you might hear.

@scottaohara scottaohara added the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Oct 24, 2024
@josepharhar
Copy link
Collaborator

Thank you for looking at this!! I'm going to close my issue in favor of this, although I listed some examples there: #1116

selectedoption (or whatever it will be named) should arguably be treated like the slot element, in that it should be made very clear to authors that, even though global html attributes can be set on it - because 'global' - none of those should be expected to work if the element is used within a select > button. Similar with ARIA attributes.

Sounds good to me. The slot element already says it accepts global attributes in the HTML spec, so I'm not sure if I can/should account for this in the HTML spec: https://html.spec.whatwg.org/multipage/scripting.html#the-slot-element

There needs to be clear author expectations for the use of the "button" within a select as well. I'm starting to wonder if it's really necessary to even have that button, just like it didn't end up being necessary to have the datalist to contain the options.

The alternative I can think of is having <div slot=button> from selectlist, which we removed in response to whatwg feedback here: #702

Perhaps for select multiple we can avoid this problem by not using/rendering a child button at all, and forcing people to build their own popovers since rendering multiple selected options in the button sounds too hard: #1102

Since, the button isn't even really used in the a11y tree.

From the rendering and focus point of view which I implemented, the button element is sort of the main thing. I started setting delegatesFocus on the select element when a child button is inserted into the select in order to make the button become the thing that gets focus.

I didn't end up setting display:contents on the select element either, so it still has a box that gets rendered, but I used UA style magic to remove borders and box decorations from the select when a button is present.

Anyway, yeah I'm not sure which of these two elements we should recommend putting accessibilty attributes etc. on.

Again, on the topic of the button, adding text/other content within the button seems like it will be a footgun. I recall that some of the rational there was that people wanted to be able to maybe add their own chevron to the button part and use an actual SVG for that. Or adding text like "choose:" before the selectedoption being essentially throwaway text, since it will be ignored. But, as anyone can put anything into that button part - do we anticipate that?

I'm not sure exactly how common it will be, but yes I think we should anticipate this and consider if/how to incorporate it into accessibility mappings.

We probably need to define a value computation algorithm. ARIA has a plan to do this for custom ARIA elements like combobox, but it seems now there's a need for select since the value can be calculated from things that aren't even defined in HTML (e.g., aria-label).

Yes I agree. How do we proceed? I'm guessing the answer to this would resolve #1116

the visible value returned to the selectedoption (not necessarily content outside of the selectedoption) probably should be what the value is exposed as. I think it's really weird that if a user chooses an option in the popup, the returned value could be displayed as / announced as something else entirely - but, if someone's going to do that, all users should arguably get that weird experience, and not have a difference between what you see vs what you might hear.

I'm guessing this is the same question - what should be announced here?

<select>
  <button>
    <selectedoption></selectedoption>
    im a button
  </button>
  <option>hello</option>
  <option label=labeltext>innertext</option>
</select>

@josepharhar josepharhar added the select These are issues that relate to the select component label Oct 29, 2024
@scottaohara
Copy link
Collaborator Author

related w3c/aria#2368

@css-meeting-bot
Copy link

The Open UI Community Group just discussed select: clarifying what should be used as the chosen value.

The full IRC log of that discussion <gregwhitworth> scott: as I just mentioned in the chat I created an issue during last week's conversation about this and created one over in ARIA
<gregwhitworth> scott: if someone is going to do things that are in my nightmares and this is scoped to what we want to return as the value but it does trickle out into other things
<gregwhitworth> scott: in speaking with aaron leventhall the implementation of this are one in the same and they may be able to do things with the button
<gregwhitworth> scott: I am mostly leaning towards that any ARIA labels or selectcontent are being added should just be ignored as these elements don't contribute to the select element's name
<sorvell> q+
<gregwhitworth> scott: I'm leaning that we don't do anything with that but it doesn't solve for the visible text that could be added but doesn't contribute to the accname
<gregwhitworth> scott: It could be used as a hint but not the description and it will be something like "Choose"
<sarah> q+
<gregwhitworth> scott: it's a mostly ridiculous usecase and the worst thing would be to do nothing at all and the best to expose it as a hint
<masonf> More typical text might be something like "Current selection: <selectedcontent>" right?
<gregwhitworth> scott: thank you for the responses on this to this jarhar
<gregwhitworth> scott: should the name come from the option text or what's returned to the selectedcontent
<gregwhitworth> scott: the value becomes "Loading..." when that isn't actually the value at all
<gregwhitworth> scott: I'm going to propose that the majority of this will be ignored and am curious is anything that I just said is a dream or does it sound reasonable
<gregwhitworth> ack sorvell
<gregwhitworth> sorvell: devs will do a bunch of weird stuff and we should endeavor to make it obvious when it's not intended
<gregwhitworth> sorvell: but the whole point of this is to have customization
<masonf> q+
<gregwhitworth> sorvell: the baseline should say what's in the selectedcontent and you don't have to show the selectedcontent element
<gregwhitworth> sorvell: it's odd, should it say nothing? I would vote for the entire contents of the button is announced if it's possible
<gregwhitworth> ack sarah
<scott> q+ to talk about no selectedoption shown
<gregwhitworth> sarah: the usecase of not using selectedcontent is not as unusual as you would think
<gregwhitworth> sarah: for myself outside of the most basic scenario I wouldn't use selectedcontent at all
<gregwhitworth> sarah: I don't think that will be all that weird especially if it's in a framework and the text in the button should be the value
<gregwhitworth> sarah: if it's Loading.. that is what sighted users are getting too
<gregwhitworth> ack masonf
<gregwhitworth> masonf: only slight difference was React in that it will commonly managing button content and not using the selectedcontent element.
<gregwhitworth> ack scott
<Zakim> scott, you wanted to talk about no selectedoption shown
<gregwhitworth> scott: ok, that's interesting
<gregwhitworth> scott: we're anticipating that people will not use the selectedcontent at all
<gregwhitworth> q+
<jarhar> q?
<masonf> q+
<jarhar> q+
<masonf> gregwhitworth: we discussed last week and people said nobody would use the <Selectedcontent> element. Frameworks will do their own thing.
<gregwhitworth> ack gregwhitworth
<masonf> gregwhitworth: this surprised me. Maybe we shouldn't have it? We need the declarative solution.
<jarhar> i feel like we have two options for how to expose the "value" of the <select> in the accessibility tree: either find the <option> which is selected and get a value out of that, or get the text content from the author provided <button>
<gregwhitworth> scott: the reason I'm thinking of that is that it opens up that we need to determine what is in the button at all and if there is nothing in there do we return the value of the option?
<sarah> q+
<gregwhitworth> scott: if there is no value then we've created a menu button
<gregwhitworth> sarah: I have an example where we have a combobox typeable or not to enable multiselect and it shows tags above or adjacent
<gregwhitworth> sarah: the text in the button would be placeholder button is still a select but the value is going somewhere else
<gregwhitworth> sarah: you would have a label and placeholder text, there isn't empty in the button
<sarah> q-
<gregwhitworth> masonf: but you need to read something out correct?
<gregwhitworth> scott: I get the usecases, how do we communicate the selectedcontent in the button and it is getting read out and it's being moved as a sibling but it's not a chosen option.
<gregwhitworth> masonf: It's a one-time picker that is moving to another input
<gregwhitworth> scott: I'm just stuck on the current behavior where they select that option and they have no confirmation that they've chosen anything
<gregwhitworth> q+
<gregwhitworth> ack gregwhitworth
<gregwhitworth> ack masonf
<jarhar> we could also use the "name" in the accessibility tree to expose the text content in the button, and use the "value" in the accessibility tree to expose the actual <option> element which is selected
<gregwhitworth> masonf: some people won't use the selectedcontent, React is a common one but there will be people that will want to use it
<gregwhitworth> masonf: both work if you're reading out all of the content in the button
<gregwhitworth> ack jarhar
<gregwhitworth> jarhar: I want to +1 to making cases that use selectedcontent work well and plan for it and make the acc tree do something good
<gregwhitworth> jarhar: there are two different things, the option element that is selected and content that is in the button. They may be the same thing they may be different
<gregwhitworth> jarhar: the select element itself has a name and a value with role of combobox and how we map them appropriately
<gregwhitworth> jarhar: what scott just said is that whatever is in the option that is selected should be in the acc tree
<sarah> q+
<gregwhitworth> scott: the accname should not come from the value
<sarah> q-
<gregwhitworth> ack sarah
<gregwhitworth> Zakim, end topic
<Zakim> I don't understand 'end topic', gregwhitworth
<gregwhitworth> Zakim, end meeting

@gregwhitworth gregwhitworth removed the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Nov 6, 2024
@josepharhar
Copy link
Collaborator

For some more thought, here is an existing example of a select element at https://x.com/settings/profile

Screenshot 2024-11-12 at 12 00 29 PM

There's a label inside the button, so the label is "Month", and the value is "February". Here is a demo I made of the same thing in customizable select, which uses aria-label to set the label to "Month": https://jsfiddle.net/jarhar/t03aw7dx/35/

@aleventhal
Copy link

And if you didn't want to repeat the text "month", you would give the <div class=label> element an id, and use aria-labelledby=[id].

@scottaohara
Copy link
Collaborator Author

scottaohara commented Nov 12, 2024

i think it's important to call out that there's no reason the label needs to be in the button part though. we did purposefully remove the use of the label element within the select/its button part, since that would go against current HTML guidance for how to use the label element.

We had also resolved that anything in the button part would become part of the calculation for the select's value - so i'm not seeing how this would solve the duplicate month announcement - unless this is suggesting that repeat content would be pruned from the accessible name?

i made up the same example in another codepen, using the label element to surround the select, so as to not put the 'label' into the button.
https://codepen.io/scottohara/pen/JjgxNRJ

one thing i noticed that is a problem with these demos, is that the label element should have made it so the entire visible select could have been clickable with a mouse to open the select's popup. but it doesn't seem that's working right now. I "have" to press on the button part specifically. similarly in the jsfiddle joey created, i can't click on any part of the select that isn't the button part to open the select. That seems wrong... but i'd assume will be resolved by some of the newer resolutions to treat the select as the primary element, and the button part as inert/inert-ish

@scottaohara
Copy link
Collaborator Author

And if you didn't want to repeat the text "month", you would give the <div class=label> element an id, and use aria-labelledby=[id].

again, unless i'm missing something here, i think if one were to do this they'd have to aria-label or aria-labelledby 'month' to be the name of the select, and then also know to aria-hidden=true the instance of the .label in the markup, so that it wouldn't take part in contributing to the value.

these might serve as two good examples of how to achieve the same visual effect, but noting CSS hoops or the ARIA hoops that one would still have to jump through, depending on the path they chose.

@aleventhal
Copy link

I don't think we should get the accessible value from the magic button's contents, but rather we should take the option that is selected, and use its subtree. If we do this, the author won't need to use aria-hidden=true. Basically, the value should be what was highlighted in the drop down, and not include any additional text before or after that comes in the button.

(Side note for Scott: the accessible value should not use any child buttons or links, because they should be associated with an action almost like aria-actions).

@scottaohara
Copy link
Collaborator Author

scottaohara commented Nov 12, 2024

i understand what you're coming from. but that's the opposite of what the group previously resolved (that what is made visible in the collapsed select should be what is exposed as the value).

so, i'm fine with going that direction, but it probably means the conversation needs to be had again and people re-evaluate why they even need to put extra content into that button part. (which i still am not sold on extra content in that button part being a good idea, but i keep losing that argument)

re:

(Side note for Scott: the accessible value should not use any child buttons or links, because they should be associated with an action almost like aria-actions).

agreed, but do we have anything to mitigate for that now, without aria-actions?
that was one reason i ended up thinking that getting the value from the button part might not be the worst idea, since at least there the value could be trimmed down as any invalid links/buttons would be pruned by authors setting them to display: none

@josepharhar
Copy link
Collaborator

Where was the resolution that we should use all the text in the button as the value?

@josepharhar josepharhar added the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Nov 13, 2024
@scottaohara
Copy link
Collaborator Author

scottaohara commented Nov 13, 2024

you're right there was no declared resolution - we ran right up to the end there. i shouldn't have said "resolved" since that's a loaded term.

but from what i recall / looking back over the minutes, with comments from greg saying he expected everything in the button part to be the value, other people echoing that on the call (though not all recorded in the minutes) and the discussion about how people would want to have an empty button and thus no value exposed - i can't imagine how we would not use the content of the button as the chosen value.

We have no guardrails up for the options themselves, no way to declare what is a description vs what is the intended name/value of an option without people having to use ARIA. Which is arguably "fine". this is v1 - get something out the door and we can improve on it. But we already have demos showing the options display one thing (more content), but cloned content is then edited via display none to present a modified version of the option.

What's returned / visible is important to accurately relay when that's all someone can see/expect to hear when they're not interacting with the popup of options. But if the value is instead pulled from the chosen option, instead of what's visible in the button part - resulting in an announced value when a value is not displayed then we're providing a different experience from what people wanted in having a button with no content in it.

so again, yes... there was no formal resolution. but everything i took away from the discussion gives me impression there isn't much room to wiggle.

to put this another way, these were the points i heard:

  • people want to be able to add extra content to their button part. how do we expose that if not part of the value? we don't even know what it's going to be. Meant to be treated as part of the value? As a label/name (though there are better ways to do that)? As a hint/description? useless restating of what someone should use a select for. e.g., "choose:".
  • what do we expect to happen if someone just puts text in their button part, but doesn't even use a selectedcontent? As a con against using the button to relay the value, this seems like one. But I'd also argue that if someone just put text in this button without a selectedcontent element, that should probably be considered misuse.
  • but, on the other hand to the above point - there were people saying they wouldn't want to use the selectedcontent element at all, and would instead use javascript to potentially render a value in the button part.
  • what people will markup as the option is not necessarily what they'll show in the collapsed state. Having the value not reflect what's shown would be awkward.
  • if nothing is rendered in the button, then there's the use case for not wanting a value shown/announced. pulling the exposed value from the option would go against this desire.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
agenda+ Use this label if you'd like the topic to be added to the meeting agenda select These are issues that relate to the select component
Projects
None yet
Development

No branches or pull requests

5 participants