Gate 32 reports a missing role on an interactive-looking element and suggests adding role="button". On CnBoardView in ConductionNL/nextcloud-vue, taking that suggestion is a regression, and axe says so without being prompted.
What was measured
The board card carries tabindex, aria-label, a click handler and an Enter handler, and it contains a <select>, which is the keyboard's only way to move a card between columns.
An element with role="button" has presentational children. So adding the role nests an interactive control inside a button, removes the one move path a keyboard user has, and collapses the card's fields into a single button label.
Mutating the component to role="button" and running axe reports nested-interactive (serious, "Interactive controls must not be nested") and aria-required-children (critical), and reddens four tests. Measured in tests/a11y/CnBoardView.a11y.spec.js, added in ConductionNL/nextcloud-vue#1226.
What was done instead
The card keeps the drag and stops being a control, cards sit in a nested list so each is a listitem, opening became a native <button> carrying the card's accessible name, and the <select> stays its sibling. That also fixed Space, which was broken before and which no version of the attribute fix would have repaired. No prop, event or slot changed.
The ask
Amend what gate 32 suggests, so it does not recommend a change that its own subject matter forbids. Either is fine:
- Keep the finding and drop the suggestion, pointing instead at "give the element a role, or make the action a native control".
- Keep the suggestion but suppress it when the element has interactive descendants (
a, button, input, select, textarea, [tabindex]), which is exactly the case where it is wrong.
The finding itself was correct and worth having: the component genuinely had no role and a broken Space key. Only the remedy misleads.
Related
Found while fixing it: check:a11y in that repo ran 9 suites and CnBoardView was not one of them, so no axe assertion had ever seen the component. It is 10 suites now. Worth asking per repo which components the a11y leg actually covers, because a component outside the list looks exactly like a component that passes.
Gate 32 reports a missing
roleon an interactive-looking element and suggests addingrole="button". OnCnBoardViewinConductionNL/nextcloud-vue, taking that suggestion is a regression, and axe says so without being prompted.What was measured
The board card carries
tabindex,aria-label, a click handler and an Enter handler, and it contains a<select>, which is the keyboard's only way to move a card between columns.An element with
role="button"has presentational children. So adding the role nests an interactive control inside a button, removes the one move path a keyboard user has, and collapses the card's fields into a single button label.Mutating the component to
role="button"and running axe reportsnested-interactive(serious, "Interactive controls must not be nested") andaria-required-children(critical), and reddens four tests. Measured intests/a11y/CnBoardView.a11y.spec.js, added in ConductionNL/nextcloud-vue#1226.What was done instead
The card keeps the drag and stops being a control, cards sit in a nested list so each is a
listitem, opening became a native<button>carrying the card's accessible name, and the<select>stays its sibling. That also fixed Space, which was broken before and which no version of the attribute fix would have repaired. No prop, event or slot changed.The ask
Amend what gate 32 suggests, so it does not recommend a change that its own subject matter forbids. Either is fine:
a,button,input,select,textarea,[tabindex]), which is exactly the case where it is wrong.The finding itself was correct and worth having: the component genuinely had no role and a broken Space key. Only the remedy misleads.
Related
Found while fixing it:
check:a11yin that repo ran 9 suites andCnBoardViewwas not one of them, so no axe assertion had ever seen the component. It is 10 suites now. Worth asking per repo which components the a11y leg actually covers, because a component outside the list looks exactly like a component that passes.