Skip to content

fix(aria-allowed-role): allow roles on a non-details summary - #5242

Merged
straker merged 7 commits into
developfrom
chut/3911-summary-allowances
Aug 4, 2026
Merged

fix(aria-allowed-role): allow roles on a non-details summary#5242
straker merged 7 commits into
developfrom
chut/3911-summary-allowances

Conversation

@chutchins25

Copy link
Copy Markdown
Contributor

Updates the roles allowed on a <summary> element based on whether it is its parent <details> element's disclosure trigger, per the ARIA in HTML update.

What & why

Per ARIA in HTML (#el-summary, w3c/html-aria#435):

  • A summary that is the "summary for its parent details" (the first summary child of a details) allows no explicit role — browsers expose it as the disclosure trigger.
  • A summary that is not the details summary (standalone, or a 2nd+ summary) is exposed as generic and allows any role.

axe previously modeled summary with an unconditional allowedRoles: false. This converts it to a variant using a condition matcher (the same pattern introduced for figure in #3443).

Scope — role side only

Issue #3911 covers both the allowed roles and the allowed aria-* attributes for summary. This PR implements the role side. The attribute side (the spec disallows aria-expanded/aria-pressed on a details-summary) is intentionally deferred — it requires an element-level disallowed-attribute mechanism axe does not have today, and is tracked in #5241.

Behavior change

A standalone / non-details <summary> now permits any role, where previously only the implicit button role was allowed. This is a spec-correct loosening; a <details>-summary's role handling is unchanged in effect (still restricted to its implicit button role).

Tests

  • get-element-spec unit — variant resolution for the three cases (details summary, non-first summary, standalone).
  • aria-allowed-role check unit — incl. an open Shadow DOM case.
  • aria-allowed-role virtual-rule — details/summary structures built with SerialVirtualNode, incl. the no-parent default.
  • aria-allowed-role integration HTML/JSON — first-summary fail, 2nd-summary pass, standalone pass, implicit-button pass.

Closes #3911

A summary that is not its parent details element's disclosure trigger is
exposed as generic and may take any role. A summary that is the details
summary continues to allow no explicit role. Per ARIA in HTML
(w3c/html-aria#435).

The attribute-side of the spec change (disallowing aria-expanded and
aria-pressed on a details summary) is tracked separately in #5241.

Closes #3911
Comment thread lib/standards/html-elms.js Outdated
Comment thread lib/standards/html-elms.js
Comment thread test/checks/aria/aria-allowed-role.js Outdated
Comment thread test/checks/aria/aria-allowed-role.js Outdated
Comment thread test/commons/standards/get-element-spec.js Outdated
Drop the inside-shadow-DOM aria-allowed-role case (no boundary crossing),
the generic get-element-spec summary cases (covered by integration), and
the implicit-button-role assertion (summary's implicit role is a separate
question being tracked independently).
@chutchins25
chutchins25 force-pushed the chut/3911-summary-allowances branch from 943e379 to 9d0d4fb Compare July 29, 2026 15:11
@chutchins25
chutchins25 marked this pull request as ready for review July 29, 2026 17:43
Copilot AI review requested due to automatic review settings July 29, 2026 17:43
@chutchins25
chutchins25 requested a review from a team as a code owner July 29, 2026 17:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates axe-core’s HTML element standards data so <summary> role allowance matches the ARIA in HTML clarification: a <summary> that is the disclosure trigger for its parent <details> disallows author-specified roles, while other <summary> elements allow any role. This is implemented via a variant condition on the summary element spec and is exercised via unit, integration, and virtual-rule tests.

Changes:

  • Update lib/standards/html-elms.js to resolve <summary> allowedRoles via a variant that detects whether it is the first <summary> child of a <details>.
  • Add unit + integration + virtual-rule coverage for: details-summary (role disallowed), non-first summary (any role allowed), and standalone summary (any role allowed).
  • Extend existing aria-allowed-role fixtures to include new <details>/<summary> cases.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/integration/virtual-rules/aria-allowed-role.js Adds virtual-rule cases covering the new summary role-allowance behavior.
test/integration/rules/aria-allowed-role/aria-allowed-role.json Adds pass/fail selectors for the new summary role cases.
test/integration/rules/aria-allowed-role/aria-allowed-role.html Adds <details>/<summary> and standalone <summary> fixtures for integration coverage.
test/checks/aria/aria-allowed-role.js Adds unit tests asserting allowed/unallowed roles for details-summary vs non-details summary.
lib/standards/html-elms.js Introduces a summary element variant to conditionally set allowedRoles.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/standards/html-elms.js Outdated
@chutchins25
chutchins25 marked this pull request as draft July 29, 2026 20:18
…the summary variant

Replace the inline condition function in the summary variant with the
serializable isSummaryForDetails matcher from #5262 so the standards
object stays function-free. The matcher intentionally throws for a
disconnected (parentless) node, so the virtual-rule test now gives the
summary a non-details parent.
@chutchins25
chutchins25 marked this pull request as ready for review August 3, 2026 20:46
…variant

Per Steve's figure-PR review conventions: remove the spec-defined variant
comments and drop the duplicated check and virtual-rule tests (the
aria-allowed-role integration tests cover the summary cases).
straker
straker previously approved these changes Aug 4, 2026
…allowances

# Conflicts:
#	test/integration/rules/aria-allowed-role/aria-allowed-role.html
#	test/integration/rules/aria-allowed-role/aria-allowed-role.json
@chutchins25

Copy link
Copy Markdown
Contributor Author

@straker rebased onto develop — the merge conflicts are resolved. They were additive fixture collisions with the figure fixtures from #5240 that landed on develop, so I kept both the figure and summary cases in the aria-allowed-role integration fixtures. All 8 fixtures pass. It's mergeable now and there are no open threads, so it should be ready for another look whenever you get a chance.

@straker
straker merged commit 3bd9875 into develop Aug 4, 2026
23 checks passed
@straker
straker deleted the chut/3911-summary-allowances branch August 4, 2026 14:59
WilcoFiers added a commit that referenced this pull request Aug 5, 2026
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 🤖 🎉
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ARIA in HTML update for summary element allowances

3 participants