Roles fixes#49
Conversation
🦋 Changeset detectedLatest commit: e219d79 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Well it gets confusing! In ARIA 1.3, I think it does (link):
HOWEVER, poking at, say,
So do we go with the spec, and assume defaults are inherited? Or do we go with browsers, which seem to imply they aren’t? I’ll see if I can dig up if the
Sorry I’m not sure I understand if this is in relation to the previous point or a new question. If it’s just the question “is this an inverse relationship?” IMO the 1.3 spec does strongly imply that: for each role, superclasses and subclasses are mirrored (I haven’t mapped them out but I’m not aware of any asymmetric relationships). |
I think the spec is ambiguous here… there is room for interpretation of the quoted section either way - if inheritance is simply of required, prohibited, and supported states and properties then it would explain why browsers (I agree with the Safari skepticism) have implemented alertdialog to suit. Perhaps worthy of an issue search and/or new issue on wai-aria to confirm?
New question and more note to myself to check what the spec says and what you’ve implemented here. From what you’ve clarified sounds like need to ensure we mirror! |
|
w3c/aria#1096 implies default values are not inherited, although the comment isn’t baked explicitly into the spec, they simply amended wording around “all constraints”. |
Yeah that’s good enough for me. Since it seems like Reviewing your list vs aria-query (very helpful, thank you! 🙏), this is what I’m seeing revisiting ARIA 1.3:
|
This one has bugged me as I was so sure this was the case as well... so not sure if there was a spec revision at some point or mandela effect, but the Update: found it, see https://www.w3.org/TR/wai-aria-1.3/#document-handling_author-errors_states-properties
So it (and other values) are user-agent fallbacks to compensate for author errors for required property and states. Could go either way whether you include these in |
Aha! Good find! So that’s why some of the roles explicate no defaults—it’s because of this table. Would be good to double-check this isn’t completely off from current browser behavior but if not, this seems like the missing piece to explain aria-query’s behavior and there’s evidence to match it a little closer. |
SetupCreated a partial test page for these (got lazy doing all of them, can if think worth it): <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ARIA Fallback Values</title>
</head>
<body>
<!-- Fallback for checkbox aria-checked -->
<div role="checkbox" aria-checked="true">Checked Checkbox</div>
<div role="checkbox" aria-checked="false">Unchecked Checkbox</div>
<div role="checkbox">Checkbox with fallback (false)</div>
<!-- Fallback for combobox aria-controls and aria-expanded -->
<div role="combobox" aria-controls="combobox-controlled" aria-expanded="true">Expanded Combobox with controls</div>
<div role="combobox" aria-controls="combobox-controlled" aria-expanded="false">Collapsed Combobox with controls</div>
<div role="combobox" aria-controls="combobox-controlled">Combobox with controls and aria-expanded fallback (false)</div>
<div role="combobox" aria-expanded="true">Expanded Combobox with aria-controls fallback (no mapping)</div>
<div role="combobox" aria-expanded="false">Collapsed Combobox with aria-controls fallback (no mapping)</div>
<div role="combobox">Combobox with aria-expanded fallback (false) and aria-controls fallback (no mapping)</div>
<div id="combobox-controlled"></div>
<!-- Fallback for heading aria-level -->
<div role="heading" aria-level="1">Level 1 Heading</div>
<div role="heading">Heading with fallback (level 2)</div>
<!-- Fallback for menuitemcheckbox aria-checked -->
<div role="menuitemcheckbox" aria-checked="true">Checked Menuitemcheckbox</div>
<div role="menuitemcheckbox" aria-checked="false">Unchecked Menuitemcheckbox</div>
<div role="menuitemcheckbox">Menuitemcheckbox with fallback (false)</div>
<!-- Fallback for menuitemradio aria-checked -->
<div role="menuitemradio" aria-checked="true">Checked Menuitemradio</div>
<div role="menuitemradio" aria-checked="false">Unchecked Menuitemradio</div>
<div role="menuitemradio">Menuitemradio with fallback (false)</div>
<!-- Fallback for radio aria-checked -->
<div role="radio" aria-checked="true">Checked Radio</div>
<div role="radio" aria-checked="false">Unchecked Radio</div>
<div role="radio">Radio with fallback (false)</div>
<!-- Fallback for switch aria-checked -->
<div role="switch" aria-checked="true">Checked Switch</div>
<div role="switch" aria-checked="false">Unchecked Switch</div>
<div role="switch">Switch with fallback (false)</div>
<div>End</div>
</body>
</html></body></html>And setup a const { expect } = require("@playwright/test");
const { voiceOverTest: test } = require("@guidepup/playwright");
test.use({ voiceOverStartOptions: { capture: "initial" } });
test.describe("Playwright VoiceOver custom iframe page", () => {
test("open test page and navigate through to the end", async ({ page, voiceOver }) => {
// Visit the test page, wait for contents to load, and then navigate to the main content.
await page.goto("http://localhost:8081/fallbacks.html", {
waitUntil: "load",
});
await expect(
page.getByRole("heading", { level: 1, name: "Level 1 Heading" })
).toBeVisible();
await voiceOver.navigateToWebContent();
// Navigate to the end of the test page.
while (!(await voiceOver.lastSpokenPhrase()).includes("End")) {
await voiceOver.next();
}
console.log(await voiceOver.spokenPhraseLog());
});
});Results
So it's a mixed bag of browsers/VO exposing this. Haven't checked windows + Narrator/NVDA or any mobile combinations. |
|
Also worth noting that there are WPT tests covering some of this fallback behaviour, e.g. https://github.com/web-platform-tests/wpt/blob/master/core-aam/heading-no-level-manual.html asserts that browsers should fallback to a level 2 heading when no |
drwpow
left a comment
There was a problem hiding this comment.
This all looks great! Thanks for all the great research and thought put into this. I’m aligned on all the changes here.
For this many role changes I think this would probably be closer to a breaking change. If we just changed it to minor I’d be happy to merge and release

Changes
Result of hacking a script to compare roles defined in
html-ariatoaria-queryand then fact checking differences against appropriate specs.Notes:
defaultAttributeValueshas been updated to reflect the union of implicit attribute value(s) for the role (for supported attributes) as well as fallback attribute value(s) for the role (for required attribute author error handling). They do not reflect attribute default values - this detail is captured insrc/lib/aria-attributes.tsinstead.How to Review
Comparison against relevant specs:
Specifically the role tables as well as the states and properties sections of WAI-ARIA.
Comparison against
aria-queryand/or user-agents (though for the prior it isn't formally coded against 1.3 and known to have inaccuracies).Checklist