feat(aria-allowed-attr): flag deprecated ARIA attributes as needs-review - #5246
Conversation
Mark aria-grabbed and aria-dropeffect as deprecated (WAI-ARIA 1.1) and add an aria-deprecated-attr check to the aria-allowed-attr rule. An element using a deprecated ARIA attribute is reported as needs-review, or as a violation when it also uses an unsupported/unallowed attribute. Closes #3341
1af5d3a to
b0bf114
Compare
There was a problem hiding this comment.
Pull request overview
Adds first-class “needs review” signaling for deprecated ARIA attributes by introducing a new aria-deprecated-attr check and wiring it into the existing aria-allowed-attr rule, so deprecated-but-valid attributes produce incomplete results unless combined with other ARIA attribute violations.
Changes:
- Marks
aria-grabbedandaria-dropeffectas deprecated instandardsand introduces a new data-drivenaria-deprecated-attrcheck that returnsundefined(incomplete) when deprecated ARIA attributes are present. - Adds
aria-deprecated-attrto thearia-allowed-attrrule so deprecated-only usage becomes “needs review”, while mixed deprecated + unallowed usage remains a violation. - Updates unit, virtual-rule, and integration fixtures to cover deprecated-only and deprecated+unallowed scenarios; removes deprecated attrs from pass fixtures that previously used them as filler.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| test/integration/virtual-rules/aria-allowed-attr.js | Adds virtual-rule coverage for deprecated-only (incomplete) and deprecated+unallowed (violation) scenarios. |
| test/integration/rules/aria-allowed-attr/passes.html | Removes deprecated attributes from pass fixtures to avoid newly-introduced incompletes in pass coverage. |
| test/integration/rules/aria-allowed-attr/incomplete.json | Expands expected incompletes to include new deprecated-attribute cases. |
| test/integration/rules/aria-allowed-attr/incomplete.html | Adds deprecated-only fixtures (single and multiple deprecated attrs). |
| test/integration/rules/aria-allowed-attr/failures.json | Adds a new expected failure case for deprecated+unallowed. |
| test/integration/rules/aria-allowed-attr/failures.html | Adds a fixture where deprecated + unallowed attribute combination produces a violation. |
| test/checks/aria/aria-deprecated-attr.js | New unit tests for the check, including data-driven configuration and Shadow DOM coverage. |
| locales/_template.json | Adds localized message templates for aria-deprecated-attr. |
| lib/standards/aria-attrs.js | Flags aria-grabbed and aria-dropeffect as deprecated: true. |
| lib/rules/aria-allowed-attr.json | Adds aria-deprecated-attr into the rule’s all checks. |
| lib/checks/aria/aria-deprecated-attr.json | Defines the new check metadata/messages (pass + incomplete singular/plural). |
| lib/checks/aria/aria-deprecated-attr-evaluate.js | Implements the new check evaluation logic based on standards.ariaAttrs[...].deprecated. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Rename the aria-deprecated-attr check to aria-no-deprecated-attr so its name reads as the passing case, since it runs in the rule's `all` array. Also drop the shadow-DOM check test that did not cross a shadow boundary. Addresses review feedback.
Dismissing as stale — this predates addressing the review. All three inline threads are resolved: the check is renamed to aria-no-deprecated-attr (positive-case naming for the all array), the in-boundary Shadow DOM test was removed, and the JSDoc data-table description was clarified. The stacked #5257 has been rebased onto the rename. Re-requesting review.
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines. ## [4.13.0](v4.12.1...v4.13.0) (2026-08-05) ### Features - **aria-actions:** add aria-actions to allowed ARIA attributes ([#5200](#5200)) ([029655d](029655d)), closes [#4584](#4584) [#5199](#5199), references [#5215](#5215) [#5215](#5215) - **aria-allowed-attr:** flag deprecated ARIA attributes as needs-review ([#5246](#5246)) ([518f3cc](518f3cc)), closes [#3341](#3341) - **aria-prohibited-attr:** allow many elements to be named and disallow label and body from being named ([#5259](#5259)) ([d8b1ea5](d8b1ea5)) - **aria-roles:** add sectionheader and sectionfooter roles ([#5238](#5238)) ([c36c109](c36c109)), closes [#4734](#4734), references [#4734](#4734) - **aria/get-aria-value:** new function to get aria values of a node ([#5109](#5109)) ([a7d8f3e](a7d8f3e)), references [#5042](#5042) - **aria/has-attr-value:** new function to check if node has aria value ([#5136](#5136)) ([61f2624](61f2624)), references [#5109](#5109) - **aria:** support role=image as equivalent to role=img ([#5248](#5248)) ([5aa8aaf](5aa8aaf)), closes [#4656](#4656), references [#5272](#5272) - **checks/aria:** support ARIA element internals properties ([#5172](#5172)) ([9b7f754](9b7f754)) - **checks/label:** support ARIA element internals properties ([#5170](#5170)) ([21c5f8b](21c5f8b)) - **checks/navigation:** support ARIA element internals properties ([#5167](#5167)) ([2c3a98f](2c3a98f)) - **commons/aria:** support ARIA element internals properties ([#5171](#5171)) ([31f09e7](31f09e7)) - **commons/dom:** support ARIA element internals properties ([#5163](#5163)) ([f0a12cf](f0a12cf)) - **commons/forms:** support ARIA element internals properties ([#5165](#5165)) ([27a4686](27a4686)) - **commons/matches/fromPrimative:** deprecate in favor of correct spelling ([#5270](#5270)) ([31cfb2e](31cfb2e)) - **commons/text:** support ARIA element internals properties ([#5169](#5169)) ([e841a33](e841a33)) - **commons/text:** support form-associated labels via element internals ([#5182](#5182)) ([57cfe0a](57cfe0a)), closes [#5045](#5045), references [#5170](#5170) [#5039](#5039) [#5151](#5151) [#5039](#5039) - **dom/getResolvedRefs:** new function to get the resolved virtual nodes of idrefs ([#5151](#5151)) ([489cdea](489cdea)), references [#5109](#5109) - **element-internals:** enable ElementInternals by default ([#5284](#5284)) ([2740d42](2740d42)), closes [#5277](#5277) - **i18n:** Add Swedish locale ([#5190](#5190)) ([dcd13f2](dcd13f2)), references [#5189](#5189) - **matches:** add inSectioningContent, hasChild, and isSummaryForDetails matches ([#5262](#5262)) ([c47cdcd](c47cdcd)) - **rules:** support ARIA element internals properties ([#5168](#5168)) ([065baf7](065baf7)) - **standards/ariaAttrs:** add caseInsensitive property for attributes ([#5224](#5224)) ([bcd791c](bcd791c)) ### Bug Fixes - **aria-allowed-role:** allow roles on a non-details summary ([#5242](#5242)) ([3bd9875](3bd9875)), closes [#3911](#3911), references [#3443](#3443) [#3911](#3911) - **aria-allowed-role:** restrict figure roles with child figcaption ([#5240](#5240)) ([178a635](178a635)), closes [#3443](#3443) - **aria-prohibited-attr:** visible aria-labelledby requires review only ([#5285](#5285)) ([fd6fa9f](fd6fa9f)) - **axe.d.ts:** make enabled property of RuleMetadata optional ([#5129](#5129)) ([90fce18](90fce18)) - **color-contrast:** fix various stacking context bugs ([#5214](#5214)) ([d5e5b04](d5e5b04)), references [#8](#8) [#5213](#5213) - **gather-internals:** handle non-HTMLElement nodes ([#5161](#5161)) ([06e84c3](06e84c3)) - **get-selector:** escape control characters in attribute selectors ([#5273](#5273)) ([4b60ac5](4b60ac5)), closes [#5204](#5204) [#5204](#5204) - **image-alt:** allow whitespace alt on presentational images ([#5218](#5218)) ([c5dd0ef](c5dd0ef)), closes [#5216](#5216) - **landmark-unique:** exclude section/form with non-landmark roles from landmark match ([#5085](#5085)) ([c5fd013](c5fd013)), closes [#4722](#4722) [#5064](#5064) - name the image role in role-img-alt and svg-img-alt metadata ([#5279](#5279)) ([995a269](995a269)), closes [#5272](#5272), references [#5248](#5248) [#5248](#5248) - **standards:** update aria-errormessage and aria-details to be idrefs ([#5157](#5157)) ([fb94f8a](fb94f8a)) This PR was opened by a robot 🤖 🎉
Flags the deprecated ARIA attributes
aria-grabbedandaria-dropeffectas "needs review".What & why
WAI-ARIA 1.1 deprecated
aria-grabbedandaria-dropeffectglobally, but axe had no signal for deprecated ARIA attributes (it already handles deprecated roles viaaria-deprecated-role).Following the approach in the issue thread (@WilcoFiers): add a new
aria-deprecated-attrcheck to the existingaria-allowed-attrrule (rather than a standalone rule), which incompletes an element using deprecated ARIA, or lets the rule fail when the element also uses an unsupported/unallowed attribute.Implementation
deprecated: trueonaria-grabbed/aria-dropeffectinlib/standards/aria-attrs.js.aria-deprecated-attrcheck: returns incomplete when any attribute withdeprecated: trueis present, pass otherwise.aria-allowed-attrrule'sallarray. Because a failing sibling check (aria-allowed-attr/aria-unsupported-attr) outranks an incomplete, an element with a deprecated attribute is:Behavior change
Any element using
aria-grabbedoraria-dropeffectnow reports underaria-allowed-attr(needs-review, or a violation when combined with an unsupported attribute). Thepasses.htmlintegration fixture used these two as "global attribute" filler on 68 pass blocks; they've been removed from those blocks (each still tests global-attribute allowance via its other global attributes), with dedicated incomplete/failure coverage added.Tests
aria-deprecated-attrcheck unit — incomplete (single/multiple), data-driven viaaxe.configure, and an open Shadow DOM case.aria-allowed-attrvirtual-rule — incomplete for a deprecated attr; violation when combined with an unallowed attr.aria-allowed-attrintegration —incomplete.html(deprecated-only, singular + plural) andfailures.html(#fail12: deprecated + unallowed → violation); 68 pass blocks updated.Follow-up
Per the issue discussion, a separate ticket will track a future standards mechanism to return "needs review" for not-recommended-but-valid roles/attributes generally.
Closes #3341