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

button with role="combobox" is not considered valid when referenced from a label element #4235

Closed
1 task done
acelaya opened this issue Nov 7, 2023 · 4 comments
Closed
1 task done
Labels
ungroomed Ticket needs a maintainer to prioritize and label

Comments

@acelaya
Copy link

acelaya commented Nov 7, 2023

Product

axe-core

Product Version

4.8.2

Latest Version

  • I have tested the issue with the latest version of the product

Issue Description

We have recently implemented a combobox component (similar to what's described in https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/).

The component's raw HTML looks something like this:

<label for="toggle-button">Options:</label>
<button 
    id="toggle-button"
    type="button" 
    role="combobox" 
    aria-expanded="false" 
    aria-haspopup="listbox"
    aria-controls="listbox"
>
    First option
</button>
<ul id="listbox" role="listbox" aria-labelledby="toggle-button" aria-orientation="vertical">
    <li
        role="option" 
        aria-disabled="false" 
        aria-selected="true" 
        tabindex="-1"
    >
        First option
    </li>
    <li 
        role="option"
        aria-disabled="false"
        aria-selected="false"
        tabindex="-1"
    >
        Second option
    </li>
</ul>

When we evaluate this with axe-core, it gets marked as invalid with this violation:

{
  "id": "button-name",
  "impact": "critical",
  "tags": [
    "cat.name-role-value",
    "wcag2a",
    "wcag412",
    "section508",
    "section508.22.a",
    "TTv5",
    "TT6.a",
    "EN-301-549",
    "EN-9.4.1.2",
    "ACT"
  ],
  "description": "Ensures buttons have discernible text",
  "help": "Buttons must have discernible text",
  "helpUrl": "https://dequeuniversity.com/rules/axe/4.8/button-name?application=axeAPI",
  "nodes": [
    {
      "any": [
        {
          "id": "button-has-visible-text",
          "data": null,
          "relatedNodes": [],
          "impact": "critical",
          "message": "Element does not have inner text that is visible to screen readers"
        },
        {
          "id": "aria-label",
          "data": null,
          "relatedNodes": [],
          "impact": "critical",
          "message": "aria-label attribute does not exist or is empty"
        },
        {
          "id": "aria-labelledby",
          "data": null,
          "relatedNodes": [],
          "impact": "critical",
          "message": "aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty"
        },
        {
          "id": "non-empty-title",
          "data": {
            "messageKey": "noAttr"
          },
          "relatedNodes": [],
          "impact": "critical",
          "message": "Element has no title attribute"
        },
        {
          "id": "presentational-role",
          "data": null,
          "relatedNodes": [],
          "impact": "critical",
          "message": "Element's default semantics were not overridden with role=\"none\" or role=\"presentation\""
        }
      ],
      "all": [],
      "none": [],
      "impact": "critical",
      "html": "<button id=\"toggle-button\" type=\"button\" role=\"combobox\" aria-expanded=\"false\" aria-haspopup=\"listbox\" aria-controls=\"listbox\">First option</button>",
      "target": [
        "#toggle-button"
      ],
      "failureSummary": "Fix any of the following:\n  Element does not have inner text that is visible to screen readers\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute\n  Element's default semantics were not overridden with role=\"none\" or role=\"presentation\""
    }
  ]
}

If we remove the role="combobobx" attribute, or add aria-label or aria-labelledby attributes, then axe-core considers it valid.

However, this document suggests linking the combobox button with a label should also be valid:

If the combobox has a visible label and the combobox element is an HTML element that can be labelled using the HTML label element (e.g., the input element), it is labeled using the label element. Otherwise, if it has a visible label, the combobox element has aria-labelledby set to a value that refers to the labelling element. Otherwise, the combobox element has a label provided by aria-label.

(Our case would be the first one described there).

This other document also indicates buttons are valid targets to be referenced by labels:

Elements that can be associated with a <label> element include <button>, <input> (except for type="hidden"), <meter>, <output>, <progress>, <select> and <textarea>.

In fact, testing the code above with a screen reader has the expected result, in whcih the label is read, followed by the button content, and the fact that it's linked to a listbox.

Removing the role="combobobx" attribute has other side effects, in which screen readers no longer announce the label.

Expectation

axe-core marks this as valid, as long as the toggle button has at least one of aria-label, aria-labelledby or a <label /> referencing to it.

Actual

axe-core considers this invalid when neither aria-label or aria-labelledby are provided, even if referenced from a <label /> element.

How to Reproduce

Pass the first html snippet above to axe-core.

Running this html file in a browser you'll get the violation mentioned above console-logged:

<html>
<body>
<div id="container">
  <label for="toggle-button">Options:</label>
  <button
    id="toggle-button"
    type="button"
    role="combobox"
    aria-expanded="false"
    aria-haspopup="listbox"
    aria-controls="listbox"
  >
    First option
  </button>
  <ul id="listbox" role="listbox" aria-labelledby="toggle-button" aria-orientation="vertical">
    <li
      role="option"
      aria-disabled="false"
      aria-selected="true"
      tabindex="-1"
    >
      First option
    </li>
    <li
      role="option"
      aria-disabled="false"
      aria-selected="false"
      tabindex="-1"
    >
      Second option
    </li>
  </ul>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/axe-core/4.8.2/axe.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
  axe.run(document.getElementById('container'), {
    runOnly: { type: 'tag', values: ['section508', 'wcag2a', 'wcag2aa'] },
    resultTypes: ['violations'],
  }).then(result => console.log(result.violations));
</script>
</body>
</html>

Additional context

N/A

@straker
Copy link
Contributor

straker commented Nov 7, 2023

Thanks for the issue. Labels on buttons have issues with assistive technologies, namely with Dragon NaturallySpeaking. Because of this we haven't supported it even though some screen readers do. We've been meaning to add an accessibility warning when we detect labels and buttons, but haven't gotten around to it yet.

@acelaya
Copy link
Author

acelaya commented Nov 7, 2023

Thanks @straker!

We've been meaning to add an accessibility warning when we detect labels and buttons, but haven't gotten around to it yet.

I'm not completely sure I understand what you mean by this.

Does this mean you are planning to warn when button+label is used instead of reporting a violation, or was this mostly a general comment that you would warn on top of the reported violation?

@straker
Copy link
Contributor

straker commented Nov 7, 2023

It'll most likely be set up as a Needs Review warning for the button-name rule rather than having it result in a violation.

@straker
Copy link
Contributor

straker commented Nov 17, 2023

Going to close this issue as we are tracking the additional message in #3696

@straker straker closed this as completed Nov 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ungroomed Ticket needs a maintainer to prioritize and label
Projects
None yet
Development

No branches or pull requests

2 participants