-
Notifications
You must be signed in to change notification settings - Fork 420
Add Experimental Example of Scrollable Listbox with Actions on Options #3372
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
base: main
Are you sure you want to change the base?
Conversation
|
Here's a branch to which you can add the necessary JS and CSS as we discussed last week. Please read the documentation I wrote in the sections for:
Please do not modify any of the JS or CSS referenced by the other listbox examples. Especially as an experimental example, it is important that we don't change the existing files. Please re-use them as much as possible, but put any new code in separate CSS and JS files. For now, in the |
|
Thanks for the awesome progress! One thing for us to discuss is how to keep the button names out of the option names. Currently, reading through the options with a screen reader causes both the name of the option and the names of each action to be announced. The aria-actions spec says the browser should prevent descendent elements from being included in the name from content calculation if the buttons are referenced by aria-actions. However, in the default state of the static HTML, the buttons are currently included inside the options without being referenced by aria-actions. I believe there are two ways to keep the buttons out of the option names:
A couple of other issues:
|
|
The ARIA Authoring Practices (APG) Task Force just discussed The full IRC log of that discussion<jugglinmike> Topic: Issue 3193: listbox example with aria-actions<jugglinmike> github: https://github.com//pull/3372 <jugglinmike> Matt_King: First of call, CurtBellew: thank you so much for the progress you've already made. It's starting to look pretty great! <jugglinmike> Matt_King: I left a comment with some discussion items <jugglinmike> Matt_King: The first is about what the browser is doing to name the options <jugglinmike> Matt_King: The issue specifically said, "let's test the meaning of aria-actions=''" <jugglinmike> Matt_King: That is supposed to communicate that actions are available <jugglinmike> Matt_King: When you're in JAWS "forms mode", you only get one of the options. You can't get any information about the options that don't have focus <jugglinmike> Matt_King: I don't know if this is working for items that don't have focus <jugglinmike> CurtBellew: I was the same way. I can see it happening in the code, but I don't know how to test it <jugglinmike> Matt_King: I just realized that I can test it with the JAWS touch cursor <jugglinmike> Matt_King: Here's the naming problem, though: Chrome calculates the name of an option from its content (unless we apply aria-label, which we don't want to do in this case) <jugglinmike> Matt_King: Because the HTML has the buttons at the time the page loads, Chrome is calculating the name of all of those options to include the name of all the buttons because they are in the content <jugglinmike> CurtBellew: I wonder about looping back around and using aria-labeledby <jugglinmike> CurtBellew: I created a test on that, but I haven't been able to reply, yet. <jugglinmike> Matt_King: That kind of breaks the intent to determine whether Chrome is doing the right thing with the naming algorithm <jugglinmike> Matt_King: My guess is that when we were talking about this in ARIA, that we would assume that the JavaScript would add the buttons to the element in real-time. <jugglinmike> Matt_King: In this case, the IDs are actually there, so you could specify aria-actions with all the IDs <jugglinmike> Matt_King: So, when we made this part of the spec (where aria-actions="" means something), my assumption was that it was supposed to support a use-case where the IDs are not available <jugglinmike> CurtBellew: I'm not averse to that. I thought we wanted these to be basically "display: none" and then come into view when they were focused <jugglinmike> CurtBellew: But I think it would work the same way either way <jugglinmike> Matt_King: They are "display: none". Does that mean that Chrome has a bug? <jugglinmike> Matt_King: If you have aria-actions specified before they are displayed... Is this an order-of-operations thing? <jugglinmike> Matt_King: What if you just disabled the method that sets the value of aria-actions? Would you still get the names of the buttons? <jugglinmike> Matt_King: I'm thinking that there is a bug in the name-from-content algorithm and that Chrome is leaving out the content <jugglinmike> Siri: This is one thing I see a lot. If you use "display: none", how does the screen reader know that there are extra actions? <jugglinmike> Matt_King: When you're in "reading mode" or a "touch cursor mode", JAWS will tell you there are actions because aria-actions="" <jugglinmike> Siri: But they are empty until you focus on it <jugglinmike> Matt_King: Right. When the screen reader wants to get the actions, what they're supposed to do is first focus the item, and then look at the value of aria-actions. So focusing the item is supposed to reveal the actions <jugglinmike> Siri: The first one is none, and it doesn't have any actions. <jugglinmike> Matt_King: JAWS has an experimental command (if you have an experimental flag enabled in Chrome) where, if you have all these conditions met, JAWS will tell you that you have actions even if the actions aren't specified, yet <jugglinmike> Matt_King: This is an interesting thing. We don't want the name to be in... <jugglinmike> Adam_Page: I'm looking at the preview, now, and I'm seeing that the buttons which are referenced by aria-actions are nested within the option <jugglinmike> Adam_Page: ...that is different than my initial tabs example, where I purposely did not nest them in that way. I had to make them siblings because I was dealing with natively-focusable elements <jugglinmike> Adam_Page: Where in this example, you are using aria-activedescendent <jugglinmike> Matt_King: That's what Sarah had said with tree-items. It's why we have a change to the naming algorithm with aria-actions. Sarah expected that normally items would be nested like that <jugglinmike> Adam_Page: I'm translating this to native HTML concepts in my mind, so to me, and option is focusable <jugglinmike> CurtBellew: It was definitely a shift for me <jugglinmike> Matt_King: Do you think we should have the buttons inside the listbox but outside the options? <jugglinmike> Adam_Page: Yes, that cognitively makes more sense to me, and it also sidesteps the accessible name problem <jugglinmike> Matt_King: Even though they are focusable, if they contain a group and if it's a parent tree-view item, then the parent has to contain a group which is the child nodes <jugglinmike> Matt_King: So you're normally putting focusables inside focusables <jugglinmike> Matt_King: It sounds like, for listbox, you're saying that it feels unnatural to place them inside the option <jugglinmike> Adam_Page: That's right, but I trust Sarah. I should review that discussion <jugglinmike> CurtBellew: I had the same response as Adam_Page, but I missed the discussion (I believe it was a TPAC) <jugglinmike> Siri: I wish we had some information. It seems like these are used a lot <jugglinmike> Matt_King: I'm noticing that with the touch cursor, JAWS is not telling me that the elements have actions, and it's also not including the names of the hidden buttons inside the names of the options <jugglinmike> Matt_King: If I activate one of these... Now, it is including it in the name. That seems like a Chrome bug, unless again, this is a timing issue. What I did was I activated with the touch cursor, and now I have the element being selected and the name of that element (including the name of all the buttons) <jugglinmike> Matt_King: I don't know whose bugs these are, but I think the naming thing is something that we need to figure out. What the intent of the spec is, at least <jugglinmike> Matt_King: I wonder if aria-actions is again on the agenda this week <jugglinmike> CurtBellew: I should be able to attend the ARIA Working Group meeting this week <jugglinmike> CurtBellew: I could ensure the timing that you're talking about happens--that the activedescendent gets updated and that then we set the actions <jugglinmike> Matt_King: It seems like we need to set the ID of the actions before the options are visible <jugglinmike> CurtBellew: Ah, yes, that's what I meant <jugglinmike> Matt_King: If you make the buttons visible, and Chrome calculates the name as a result of that, and then you add the value of aria-actions, then is Chrome going to re-calculate the name after that? <jugglinmike> Matt_King: Maybe that's the question for the ARIA Working Group--"what is the expectation, here?" <jugglinmike> CurtBellew: It feels like it won't recognize that the IDs exist or, as you said, it will just sort of re-calculate, and you'll get what we have, now <jugglinmike> Matt_King: The touch cursor is also seeing all the icons--the graphics. We probably want to hide those with aria-hidden <jugglinmike> Siri: It's reading all the names of the buttons that show up? <jugglinmike> Matt_King: Yeah, that's one of the problem <jugglinmike> Matt_King: It feels like it's really janky to place the buttons inside of the element <jugglinmike> Matt_King: Maybe aria-actions="" doesn't apply in that scenario. Maybe if you're going to place the buttons inside of the element, you need to... <jugglinmike> Adam_Page: ...have a persistent relation? <jugglinmike> Matt_King: Maybe... <jugglinmike> Matt_King: I really wonder about the intent. I feel a lot of confusion here <jugglinmike> Matt_King: In the mean time, if you could place aria-hidden on those icons (just like we already use it with the "checked") icon <jugglinmike> CurtBellew: Got it <jugglinmike> Matt_King: What do we want to do when someone has marked something a "favorite"? I wonder if the favorite icon should be first or last within the name. It seems like it should be part of the name because it's not a state <jugglinmike> CurtBellew: Right now, it's just using an aria-pressed, so that makes sense! <jugglinmike> Adam_Page: This is where a relatable real-world example could be helpful. It's feeling a little contrived right now. Who's out there favoriting elements? <jugglinmike> CurtBellew: I have a few bullet points to take care of, so I'll dot hat <jugglinmike> s/dot hat/do that/ <jugglinmike> Adam_Page: This might be a good opportunity to use text alternatives for CSS "content" in pseudo-elements <jugglinmike> Adam_Page: It's a special syntax for the "content" property for the CSS "content" attribute <jugglinmike> Matt_King: Adam_Page, can you make a suggestion for CurtBellew in the "files" tab of the GitHub pull request? <jugglinmike> Adam_Page: Sure <jugglinmike> Siri: Could you add a link to the IRC chat, as well? <jugglinmike> Matt_King: Okay, we're out of time. Thanks everyone! We'll meet same time, same station next week <jugglinmike> Zakim, end the meeting |
| display: inline; | ||
| } | ||
| span.uparrow::before { | ||
| content: "↑"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| content: "↑"; | |
| content: "↑" / ""; |
Heya, @curtbellew / @mcking65 — here’s the alt text technique for pseudo-content I mentioned during the call.
| padding: 2px; | ||
| } | ||
| span.downarrow::before { | ||
| content: "↓"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| content: "↓"; | |
| content: "↓" / ""; |
| padding: 2px; | ||
| } | ||
| span.favorite[aria-pressed="true"]::before { | ||
| content: "★"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| content: "★"; | |
| content: "★" / ""; |
| padding: 2px; | ||
| } | ||
| span.favorite:not([aria-pressed])::before, span.favorite[aria-pressed="false"]::before { | ||
| content: "☆"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| content: "☆"; | |
| content: "☆" / ""; |
| padding: 2px; | ||
| } | ||
| span.delete::before { | ||
| content: "🗑"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| content: "🗑"; | |
| content: "🗑" / ""; |
|
The ARIA Authoring Practices (APG) Task Force just discussed The full IRC log of that discussion<jugglinmike> Topic: Issue 3193: listbox example with aria-actions<jugglinmike> github: https://github.com//pull/3372 <jugglinmike> Matt_King: I had a meeting with Sarah Higley and Brett Lewis about this yesterday <jugglinmike> Matt_King: One of the questions was around, "why are the button names getting included in the label?" <jugglinmike> Matt_King: Sarah offered to review the code of the pull request <jugglinmike> Matt_King: She didn't think it was a problem with that code, though <jugglinmike> Matt_King: Her suspicion is that the browser is not yet fully implementing the spec <jugglinmike> Matt_King: We verified that when the action buttons are hidden, they are not in the name <jugglinmike> Matt_King: Because this is name from content, the event that causes the name to be re-calculated is the change in style--away from "display: none" <jugglinmike> Matt_King: When Sarah was looking at the code, she agreed that it appeared to be authored correctly <jugglinmike> CurtBellew: That's great to know. I was really confused about this. It makes sense that the actions need this information <jugglinmike> Matt_King: What we could do for now (unless someone ends up proving otherwise) is just assume that it's a browser bug <jugglinmike> Matt_King: Just knowing that the code event that causes the browser to recalculate the name is when you change the "display" CSS property value <jugglinmike> Matt_King: Okay, that clears up one thing <jugglinmike> Matt_King: There was some feedback that I provided in there related to how the keyboard works--the left and right arrow getting back to the current option <jugglinmike> CurtBellew: I was holding off while waiting for a resolution to the question about the name <jugglinmike> CurtBellew: I don't know if I'll have time to look at it this week, but I should have time by next week (perhaps as early as this coming Friday) <jugglinmike> Matt_King: From a priority standpoint, the most important thing is representing the starred state in the name of the option somehow <jugglinmike> Matt_King: We should talk about what should happen <jugglinmike> Matt_King: What should the screen reader experience be if you choose the "favorite" option from the actions? <jugglinmike> CurtBellew: If we use aria-label to add "favorite", we'll wind up changing the name <jugglinmike> Matt_King: If you favorited something, and you up and down arrow through the list, you need to know <jugglinmike> CurtBellew: If we use a label, or if we use hidden text... <jugglinmike> Matt_King: For a sighted user, when the buttons are not displayed, and you're just looking at the list--how is the "favorited" state shown to the user? <jugglinmike> CurtBellew: you don't see it until you have focused <jugglinmike> Matt_King: That seems like a shortcoming in the visual design <jugglinmike> CurtBellew: There is a selected checkbox that we could replace <jugglinmike> Matt_King: Yes. We're not doing multi-select in this example, so the checkbox is useless <jugglinmike> Adam_Page: In Gmail, it has a "favorite" toggle that is always visible <jugglinmike> CurtBellew: When you hover, the actions appear to the right. <jugglinmike> CurtBellew: you typically see this kind of thing to the left of the text <jugglinmike> Matt_King: Maybe emulating Gmail is not the most illustrative <jugglinmike> Matt_King: Maybe just make a display icon on the left <jugglinmike> Adam_Page: I agree. I like having something persistent on the left. And furthermore, having something to display the absence (rather than simply displaying nothing at all) <jugglinmike> Matt_King: It sounds like you're suggesting that the favorite should not be an action. That it should be a visually persistent thing <jugglinmike> Adam_Page: Can it be both? <jugglinmike> Matt_King: It could <jugglinmike> Adam_Page: In a lot of ways, it feels like what I'm suggesting is more like in the tabs example <jugglinmike> Adam_Page: This is a more sophisticated design. One action is persistently visible and three others are not <jugglinmike> CurtBellew: What would the keyboard interaction be like to designate a favorite? <jugglinmike> Siri: When you favorite or do anything on that, when the star is hollow or filled in, it is not shown to the user anymore. Only the selected part of the listbox is shown <jugglinmike> Matt_King: That's what we're talking about changing <jugglinmike> Siri: I would say to show all the actions available for the selected item <jugglinmike> Matt_King: We could make "space" and "enter" be the keyboard shortcut for the favorite, and then the other actions are accessible via the means already documented <jugglinmike> CurtBellew: I like that idea <jugglinmike> Matt_King: If it's favorited, you would want the icon to be part of the accessible name and not aria-hidden. But if it's not favorited, you would not want that piece of information to be part of the accessible name <jugglinmike> CurtBellew: I've built this on top of listbox, but I should be able to make the necessary overrides to implement this behavior <jugglinmike> Siri: If the user moves up and down with the arrows, will the user be informed via aria-live? <jugglinmike> Matt_King: Ah, if you choose the option to move up or down <jugglinmike> Matt_King: I agree; I think aria-live would be a good way to implement that <jugglinmike> CurtBellew: I almost forgot about that. Thanks for the reminder, Siri! <jugglinmike> Matt_King: I can net all of this out into a checklist of changes... But only if it will speed you up! <jugglinmike> CurtBellew: definitely! <jugglinmike> Matt_King: This example was really helpful in that discussion with Brett and Sarah. Even if we don't publish this before TPAC, we can always use the PR preview during TPAC. <jugglinmike> Matt_King: I think we've worked out the things that we need to work out for this one for now. I'll make that list of changes for you, CurtBellew |
Resolve #3193.
WAI Preview link for Scrollable action exmaple
WAI Preview Link (Last built on Thu, 16 Oct 2025 20:13:48 GMT).