I am building a user form that contains a date input field and a time dropdown picker. It needs to be accessible and compliant with the WCAG. I think it’s more intuitive for sighted users if we have a visual label to accompany the form controls. In order for screen reader users to have access to the content in the visual labels, I need to explicitly link the labels to the form controls.
As the dropdown is not a search field dropdown, it just has a trigger button.
Problem:
When the buttons contain textual content, screen readers such as NVDA do not expect any further labeling as it's usually not necessary. Adding further labeling, causes the screen reader announcements to not behave as expected. For example, the aria-label or aria-labelledby content is read and the content inside the button is not read. It doesn't seem like this kind of behavior is supported by screen readers for the button role.
Examples:
{/* works: start time, edit field, blank */}
<label id="form-label-4">Start date</label>
<input type="date" aria-labelledby="form-label-4"></input>
{/* does not work: start time, button */}
<label id="form-label-2">Start time</label>
<button aria-labelledby="form-label-2">12:00 PM</button>
{/* works, but not the desired effect: button, 13:00 PM. end time */}
<label id="form-label-3">End time</label>
<button aria-describedby="form-label-3">13:00 PM</button>
{/* does not work: button, start time */}
<button aria-label="Start time">13:00 PM</button>
How can I achieve the desired result?
CodePudding user response:
The problem is that you're trying to assign both a label and a value to a button component, but that's not what a button is designed to do - it's meant to have a label and potentially a state (e.g., for toggle buttons). You've created a button menu that behaves as a select-only combobox but isn't semantically a combobox.
In my view, you have two options:
Re-write the Start Time and End Time button menus as select-only comboboxes. You can refer to the WAI-ARIA Practices example to get a sense of how this component should behave with a screen reader.
You could add a second non-visible label to your button with the selected time and link it to the button using
aria-describedby
. This will announce the label, the role, and the value in the order you want:
<label id="form-label-2">Start time</label>
<label id="form-label-3">12:00 PM<label>
<button aria-labelledby="form-label-2" aria-describedby="form-label-3">12:00 PM</button>