Skip to content

feat: aria-actions addition to the ARIA spec - #1805

Open
smhigley wants to merge 30 commits into
mainfrom
secondary-actions
Open

feat: aria-actions addition to the ARIA spec#1805
smhigley wants to merge 30 commits into
mainfrom
secondary-actions

Conversation

@smhigley

@smhigley smhigley commented Sep 16, 2022

Copy link
Copy Markdown
Contributor

🚀 Netlify Preview:
🔄 this PR updates the following sspecs:

Resolves #1440 by adding the aria-actions attribute

This has a dependency on the changes in #1454.

PR tracking

Check these when the relevant issue or PR has been made, OR after you have confirmed the
related change is not necessary (add N/A). Leave unchecked if you are unsure. Read the
Process Document or
Test Overview for more information.

Test, Documentation and Implementation tracking

Once this PR and all related PRs have been been approved by the working group, tests
should be written and issues should be opened on browsers. Add N/A and check when not
applicable.


Preview | Diff

@cookiecrook

Copy link
Copy Markdown
Contributor

@aleventhal @jcsteh @mcking65

Adding reviewers to get some more perspectives on this. The description is missing in the PR, but the relevant discussion is in #1440, and I think the idea is sound.

@cookiecrook

Copy link
Copy Markdown
Contributor

@smhigley I updated the property description to move this along. Nearly ready IMO. Some comments in the diff.

Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated

@mcking65 mcking65 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.

I think we need a discussion of whether aria-actions should be allowed on elements that are not focusable or referenced by aria-activedescendant. I see potentially big problems with elements that are containers with boundaries that screen readers treat as invisible. I also am concerned about the idea that it could be used on a dialog, which by default, should not be focusable; that is only a fall-back error condition where a dialog would get focus.

I have added several suggestions where I think the language needs more clarity.

Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
@mcking65

Copy link
Copy Markdown
Contributor

To what extent is avoiding creating additional vectors for the active finger printing mentioned in section 11 a consideration in the design of this feature? I see some language that appears to be aimed in that direction, such as the requirement for using clicks and default actions. However, as written, it appears to me that it is all author responsibility, and is thus a wide open door.

I wonder if it would be possible to have requirements that:

  1. Require one of the following to be true about the element with aria-actions:
    1. It is focusable
    2. It is referenced by aria-activedescendant from a focusable element
    3. It is inside of an editor (not sure how to spec this yet)
  2. User agents do not expose the actions in the accessibility API unless one of the following is true:
    1. The element has DOM focus
    2. aria-activedescendant is referring to it from an element with DOM focus
    3. The element is inside an editor that has focus

@aleventhal

aleventhal commented Feb 10, 2023

Copy link
Copy Markdown
Contributor

Matt, why do we need the focusable rule? Would it not be enough for the source to be visible, and the target to be visible & clickable? To activate the action, the browser can send it a click as if a real mouse click occurred.

@cookiecrook

Copy link
Copy Markdown
Contributor

To what extent is avoiding creating additional vectors for the active finger printing mentioned in section 11 a consideration in the design of this feature? I see some language that appears to be aimed in that direction, such as the requirement for using clicks and default actions. However, as written, it appears to me that it is all author responsibility, and is thus a wide open door.

I think you may misunderstand. If an author doesn't use a click, it won't reveal anything new about the user. The UI just may not work in some scenarios.

We purposefully limited AT's trigger-ability here to a click (rather than a new event or direct API call) to avoid risk of detection.

@cookiecrook

cookiecrook commented Feb 10, 2023

Copy link
Copy Markdown
Contributor

I wonder if it would be possible to have requirements that:

Those are all much too rigid/restrictive in my opinion. And possibly too screenreader specific.

AT focus or focus-in is an expectation, but not DOM focus. Otherwise we may not be able to make this work well for other AT like Switch Control, Voice Control, etc. Likewise Dragon on Windows, Android's Switch Access, etc.

@lukewarlow

Copy link
Copy Markdown
Member

Are there any open questions with this functionality that needs any help?

@TKDev7

TKDev7 commented Apr 6, 2024

Copy link
Copy Markdown

What else is needed to get this PR merged?

@cookiecrook

cookiecrook commented Apr 19, 2024

Copy link
Copy Markdown
Contributor

@mrhbs wrote:

What else is needed to get this PR merged?

  • @smhigley If there are no more queued changes in your to-do list or major updates since my review, you could mark the draft PR as ready for review.
  • Then we need a second reviewer to approve.
  • We can't write automated WPT tests for this yet, but we could also use some manual test cases the implementors could develop against.
  • Then we need linked tracking issues in each of the 3 major engines.
  • Once two engines have implemented the feature, then the PR can be merged.

@daniel-montalvo

Copy link
Copy Markdown
Contributor

@mcking65 The latest changes introduced to respec are severely affecting the ARIA previews. We do need the latest updates for them to work properly. For fixing the conflicts I would prefer for @smhigley to take a pass at the main index.html file because it seems it's been a long time since we last merged main into this feature branch and conflicts are very long, which makes it difficult to resolve them with a screen reader.

@janewman janewman 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.

Thanks for putting this together, just a quick question

Comment thread core-aam/index.html
<li>`nActions`: add the number of accessible nodes referenced by `aria-actions` that are exposed in the accessibility tree</li>
<li>`name`: if the corresponding target node has a DOM id, return that DOM id prefixed by "custom_". Otherwise, return "custom".</li>
<li>`localizedName`: return the corresponding target node's accessible name.</li>
<li>`doAction`: behave as if `doAction(0)` were called on the corresponding target accessible node.</li>

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.

What about description and keyBinding? Do we want to specify the expected value? (even if that is S_FALSE)
https://accessibility.linuxfoundation.org/a11yspecs/ia2/docs/html/interface_i_accessible_action.html

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.

Good question. The behaviour of IAccessibleAction::description and ::keyBinding is currently undocumented in the spec even for the primary action, let alone secondary actions... and that's before we even get to aria-actions. :) To make matters worse, Gecko and Chromium seem to disagree a little about how these should behave for both types of actions.

Although a lack of documentation for one case isn't a good excuse for failing to document another case, we're somewhat constrained here in that we're using the same interface for both sets of actions. For example, I think it'd be kinda weird if we returned E_NOTIMPL for description(0), but returned a useful string or S_FALSE for description(1).

For what it's worth, Gecko maps description(n) directly to localizedName(n). Chromium returns E_NOTIMPL for description(n) in all cases. I don't think there's anything useful we can do for description, so I don't feel strongly about any particular mapping.

keyBinding is messier. Gecko returns S_FALSE for n == 0, E_INVALIDARG for n >= 1. Chromium returns the access key (but just the key itself, not the modifier; e.g. b, not alt+b) for primary/secondary actions, but returns E_INVALIDARG for aria-actions. There probably is some utility in exposing the keyboard shortcuts associated with aria-actions, so perhaps we should make keyBinding(0) equivalent to this->accKeyboardShortcut and keyBinding(ariaActionIndex) equivalent to ariaAction->accKeyboardShortcut.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@jcsteh do you think the keybinding should be spec'd or come from the browser? I was thinking about it, and wondering if this should be mapped in the API or left undefined to allow NVDA/JAWS to choose whatever makes sense independently. But obviously would defer to your opinion there.

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.

A thing to keep in mind here is that IAccessible2 clients can't get at the target node. They can only perform the action (doAction) and query the properties exposed by this interface: name, localizedName, description and keyBinding. So, if we don't expose the key binding for the target, the client can't get at it any other way.

Whether the client will use that is an open question. I guess I could see a use case where the client presents a menu of actions, and in that menu, the client shows the action name as well as the key binding, effectively allowing the client to "discover" the key binding for quicker access to the action next time. That seems like it could be useful.

I can't see any harm in exposing it; we're not doing anything with this method right now. So unless someone else can see a downside, I guess we should just do it.

Something like this:

<li>`keyBinding`: return the corresponding target node's keyboard shortcut; i.e. as if `accKeyboardShortcut` were queried on the corresponding target accessible node.</li>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh, are you talking about using it to map any author-defined keyshortcuts on the action? That makes sense to me, I thought you meant making up a specific default keyboard shortcut for aria-actions and putting that there, which I didn't really see a reason to do.

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.

Oh, are you talking about using it to map any author-defined keyshortcuts on the action?

Yes. This would also apply to accesskey, since accesskey is also mapped to accKeyboardShortcut.

I thought you meant making up a specific default keyboard shortcut for aria-actions and putting that there, which I didn't really see a reason to do.

Oh, I can see why that would have been confusing. That's a terrible idea and definitely not what I intended to suggest. 😂

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

haha awesome, then what you're saying makes complete sense to me, I'll update the mapping :D

brave-builds pushed a commit to brave/chromium that referenced this pull request Jun 2, 2026
Fix two IAccessibleAction methods that didn't properly handle
aria-actions indices:

- get_description: was returning E_NOTIMPL unconditionally. Now
  validates the action index and returns S_FALSE (no description
  available for any action type today).
- get_keyBinding: was bounds-checking against existing actions only
  (things like kDoDefault (click), kFocus, kScrollUp) causing valid
  aria-actions indices to return E_INVALIDARG. Now includes
  aria-actions in the bounds check.

I've raised a comment in the Spec PR for these mappings to be explicit:
w3c/aria#1805 (comment)

With these fixes, all six IAccessibleAction methods properly handle the
full action index range (existing actions + aria-actions).

Bug: 514751946
Change-Id: Icd1088913e21fca42f616abf66c04f69d808a19c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7896745
Auto-Submit: Jacques Newman <janewman@microsoft.com>
Commit-Queue: Jacques Newman <janewman@microsoft.com>
Reviewed-by: Benjamin Beaudry <benjamin.beaudry@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#1640359}
Comment thread core-aam/index.html
<th><abbr title="User Interface Automation">UIA</abbr></th>
<td>
<span class="property">
Custom Property: <code>AccessibleActions</code>, an element array of accessible nodes matching IDREFs. If the referenced nodes are in the accessibility tree, expose the property using the following custom property registration information:

@janewman janewman Jun 3, 2026

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.

According to Microsoft documentation, we don't have the option to use UIAutomationType_ElementArray :(

A custom property must have one of the following data types specified by the UIAutomationType enumeration. No other data types are supported for custom properties.

  • UIAutomationType_Bool
  • UIAutomationType_Double
  • UIAutomationType_Element
  • UIAutomationType_Int
  • UIAutomationType_Point
  • UIAutomationType_String

That all said, on my windows 11 VM, using UIAutomationType_ElementArray works just fine, but doesn't in the chromium win10 bots, so maybe this is changing? Accessibility Insights wasn't able to reflect the custom property when it returned an element array either, but a local test UIA client implementation had no such issue.

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.

Heh, I pointed out the same thing in #1805 (comment). Apparently, this is a documentation oversight; see #1805 (comment):

I checked with Doug Geoffray, and it looks like it's just an oversight in the documentation. I believe any of the listed types can also be used as an array type for a property value.
We should be good to go to create AccessibleActions as a UIAutomationType_Element[] array 👍

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Heh yes, I checked with Doug when I originally wrote the mapping, then again when Jamie asked :D

I have no idea who owns that documentation but I suppose at this point I should probably try to find out

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.

This certainly appears to be a change with win11, on win10 this doesn't appear to work.
I'll agree that this documentation should be updated.
Do we need to call out that this won't work on older versions of windows? Given Windows 10 is past the support date, maybe we don't need to worry.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah I wouldn't really stress about it as long as it would just fail to map aria-actions without causing any other errors.

@mcking65 mcking65 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.

Three Editorial suggestions for clarity.

Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
<pdef>aria-actions</pdef>
<div class="property-description">
<p><a>Identifies</a> a related element or elements whose primary activation (<code>click</code> event) will trigger a behavior or operation relevant to the referencing user interface object, such as the close button for a tab, or a reply button relevant to the email message that references it.</p>
<p>The <code>aria-actions</code> attribute allows an element to reference other interactive elements that trigger actions related to the referencing element. For example, in the inbox of a web mail application, the focused element representing an email message could reference buttons that perform actions on that email, such as Reply, Forward, and Delete. Actions are triggered by pointer events (click, tap) that can be simulated by assistive technologies.</p>

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.

Suggested change
<p>The <code>aria-actions</code> attribute allows an element to reference other interactive elements that trigger actions related to the referencing element. For example, in the inbox of a web mail application, the focused element representing an email message could reference buttons that perform actions on that email, such as Reply, Forward, and Delete. Actions are triggered by pointer events (click, tap) that can be simulated by assistive technologies.</p>
<p>The <code>aria-actions</code> attribute allows an element to reference other interactive elements that trigger actions related to the referencing element. It is particularly useful for exposing contextual actions to assistive technology users in scenarios where action buttons become visible on hover or focus. For example, in the inbox of a web mail application, the focused element representing an email message could reference buttons that perform actions on that email, such as Reply, Forward, and Delete. Actions are triggered by pointer events (click, tap) that can be simulated by assistive technologies.</p>

@smhigley smhigley Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't actually know if we want to call out hover/focus actions as being a better fit for aria-actions than statically available actions -- I think it's often just as needed for the latter in cases where you'd expect a user to be navigating in forms mode and not discover buttons that are not arrow stops in the menu/listbox/tablist/etc.

beckysiegel pushed a commit to chromium/chromium that referenced this pull request Jun 4, 2026
The latest spec PR(w3c/aria#1805) requires
has-actions to be exposed on every host whose role supports aria-actions
and that sets the attribute, regardless of whether any referenced target
survives IsValidAriaActionsTarget.

Widen the kHasActions gate in AXObject::SerializeUnignoredAttributes so
the attribute is added when aria-actions is set on a supporting role, in
addition to the existing path that triggers when kActionsIds is
non-empty (which covers implicit-actions on menuitem-like roles). The
previous gate keyed only on a non-empty kActionsIds, leaving assistive
tech unable to distinguish "no aria-actions" from "aria-actions present
but all targets filtered."

Bug: 408040289, 514751946
Change-Id: Id621008fefd84a8b999565049735ff2c6f47a6a4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7895414
Reviewed-by: Benjamin Beaudry <benjamin.beaudry@microsoft.com>
Commit-Queue: Jacques Newman <janewman@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#1641975}
@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

🚀 Deployed on https://deploy-preview-1805--wai-aria.netlify.app

@github-actions
github-actions Bot temporarily deployed to pull request June 4, 2026 23:28 Inactive
@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

🚀 Deployed on https://deploy-preview-1805--wai-aria.netlify.app

@github-actions
github-actions Bot temporarily deployed to pull request June 4, 2026 23:57 Inactive
@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

🚀 Deployed on https://deploy-preview-1805--wai-aria.netlify.app

@github-actions
github-actions Bot temporarily deployed to pull request June 5, 2026 00:07 Inactive
@github-actions

github-actions Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

🚀 Deployed on https://deploy-preview-1805--wai-aria.netlify.app

@github-actions
github-actions Bot temporarily deployed to pull request June 7, 2026 14:37 Inactive
smhigley added a commit to smhigley/sdk-api that referenced this pull request Jun 12, 2026
In creating the [aria-actions PR](w3c/aria#1805), it came up that the list of supported value types for a custom UIA property didn't include arrays, even though arrays are supported. This PR updates the docs to explicitly include the respective array types for each of the supported types.
beckysiegel pushed a commit to chromium/chromium that referenced this pull request Jun 23, 2026
The aria-actions spec PR (w3c/aria#1805) §6.8
includes an Author SHOULD that targets be visible when the host has DOM
focus. Today we gave this behavior is chromium due to
CanSetFocusAttribute() returning false for the hidden subtree, and
IsValidAriaActionsTarget() already rejects targets that are not
keyboard-focusable.

This change codifies the existing behavior to protect against
regression, with no behavioral change.

Bug: 408040289
Change-Id: I12e4bc2bd8f2b1cac9f96dbcac1979ea085c3604
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7852706
Commit-Queue: Kurt Catti-Schmidt <kschmi@microsoft.com>
Reviewed-by: Kurt Catti-Schmidt <kschmi@microsoft.com>
Auto-Submit: Jacques Newman <janewman@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#1651177}
chutchins25 added a commit to dequelabs/axe-core that referenced this pull request Jul 16, 2026
…PG test

Prohibit aria-actions on the 11 name-prohibited roles per w3c/aria#1805, add
an allowEmpty pass case, and bump aria-practices to re-enable the tabs-actions
APG example. aria-required-children / nested-interactive don't yet support the
aria-actions pattern, so they're disabled per-page pending #5215.

Closes #4584
chutchins25 added a commit to dequelabs/axe-core that referenced this pull request Jul 17, 2026
## Summary

Adds `aria-actions` to axe-core's known ARIA attributes so it is
recognized as valid, allowed, and prohibited on the roles the spec
prohibits it on — and re-enables the APG `tabs-actions` example that had
been disabled for lack of `aria-actions` support.

Per the [spec draft](w3c/aria#1805),
`aria-actions`:

- **Value type:** ID reference list → `idrefs`
- **Global:** yes (like `aria-describedby`)
- **Empty allowed:** yes — the spec permits `aria-actions=""` (the
deferred-DOM case) → `allowEmpty: true`
- **Prohibited roles:** the name-prohibited roles the spec also
prohibits it on (all axe `prohibitedAttrs` roles except
`none`/`presentation`, which the spec still permits)
- **ElementInternals reflection:** `ariaActionsElements`

## Accessibility-supported rationale

Following the [Impact on
ARIA](https://github.com/dequelabs/axe-core/blob/develop/doc/accessibility-supported.md#impact-on-aria)
decision framework:

1. Supported by all platforms? No — shipped in WebKit and Firefox;
**Chromium pending**.
2. Does its use negatively impact accessibility? **No** — unsupported
browsers simply ignore the attribute (progressive enhancement), and the
spec hard-guards exposure. → **allow.**

> **Note for reviewers:** the ARIA spec change is still [PR
#1805](w3c/aria#1805), not yet merged — this
aligns to the two engines shipping ahead of spec approval. We can patch
the config later in the unlikely event the spec shifts.

## Changes

**Attribute recognition** — `lib/standards/aria-attrs.js`: add the
`aria-actions` entry (`idrefs`, global, `allowEmpty`).

**Prohibited-on-role** — `lib/standards/aria-roles.js`: add
`aria-actions` to `prohibitedAttrs` for `caption`, `code`, `deletion`,
`emphasis`, `insertion`, `mark`, `paragraph`, `strong`, `subscript`,
`superscript`, `suggestion`. Per
[w3c/aria#1805](w3c/aria#1805) these roles
prohibit it; `none`/`presentation` do not, so they are left unchanged.

**APG test re-enable (Closes #4584)** — bump `aria-practices` to latest
`main` (the `tabs-actions` page did not exist at the previously pinned
commit) and remove it from `skippedPages`. axe recognizes the attribute
but not the authoring *pattern*, so `aria-required-children`
(tabs-actions) and `nested-interactive` (listbox-actions) are disabled
per-page pending #5215.

**Review feedback** — update the stale `wai-aria-1.1` `Source:` comment
to the unversioned WAI-ARIA URL; add an `aria-actions=""` pass case
exercising `allowEmpty`.

## Testing

- `get-global-aria-attrs`, `aria-prohibited-attr` (check +
virtual-rule), `aria-valid-attr`, `aria-allowed-attr`,
`aria-valid-attr-value` unit + integration tests ✓
- Full APG suite green (76 passing) ✓
- `npm run build` clean; no auto-generated committed files change

## Follow-ups

- #5215 — teach `aria-required-children` / `nested-interactive` about
the `aria-actions` pattern, then remove the per-page disables in
`apg.spec.js`

Closes #5199
Closes #4584
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Agenda ARIA 1.3 spec:aria spec:core-aam waiting for implementations Cannot be merged until there are two browser impls or one impl + impl commit

Projects

Status: Needs updates from review

Development

Successfully merging this pull request may close these issues.

Secondary actions on items in composite widget roles