-
Notifications
You must be signed in to change notification settings - Fork 847
Description
One of the difficulties we ran into mapping axe-core results to RGAA was that RGAA in many places breaks things down different from how WCAG did. Requirements for links are separate from requirements for buttons, which are separate for form fields. That kind of thing. RGAA also distinguishes between bold and regular text for example. In WCAG we have similar (although fewer) issues like this. For example in #4902. Axe often map ARIA to 4.1.2 even if the element that attribute is on isn't interactive. One way to solve this would be to split those rules up. But that quickly gets messy, especially if trying to keep an accurate mapping to multiple standards.
Another problem with axe-core's mappings to accessibility requirements is that there are simply too many of them. Axe-core now includes a mapping for WCAG 2.x, Section508, Trusted Tester v5, ACT Rules, EN 301 549 v3, and RGAA v4. Undoubtably we'll be adding more of them in the future. There are rules with 14 tags now. That's only going to get longer as new versions of these standards come out.
Dynamic requirement mapping
Instead of having tags both for standards / levels (WCAG2a, RGAAv4) and for requirements (wcag111, rgaa-1.1.1) axe should only have tags ro standards and levels.
{
"id": "image-alt",
"tags": ["cat.text-alternatives", "wcag2a", "section508", "TTv5", "EN-301-549", "ACT", "RGAAv4"],
"requirements" {
"wcag2a": "wcag111",
"section508": "section508.22.a",
"TTv5": ["TT7.a", "TT7.b"],
"EN-301-549": "EN-9.1.1.1",
"ACT": "ACT-23a2a8",
"RGAAv4": "RGAA-1.1.1"
},
"..."
}To allow dynamic mapping, what we can do is add selectors and matches methods, which work similar to how the rule's selector and matches methods work. A mapping with a selector and/or matches is only applied if true:
{
"requirements": {
"RGAAv4": [
{ "requirement": "RGAA-6.1.5", "matches": "no-role-matches" },
{ "requirement": "RGAA-11.9.2", "selector": "button, [role=button]" }
]
}
}Axe results
Which node is tested under which requirement is then exposed through a new requirements property on NodeResult:
type AccessibilityStandard = 'wcag2a' | 'wcag2aa' | ...
interface AccessibilityRequirement {
[AccessibilityStandard]: string[]
}
interface NodeResult {
requirements: AccessibilityRequirement
}Documentation
Documenting which rules map to which requirements does get a little more complicated with conditional mappings. The way I'd propose we do this is to have some styling / indicator on requirements that are conditional, and for rules that have conditional mappings to have a section in the rule help page that explains what applies when.
Rollout and breaking changes
This change should eventually lead to removing requirement-specific tags from axe-core. That's a breaking change, so I think we'll need a good bit of lead-up time. I think the best way to do this is to put the static mapping both in tags and in this new requirements structure. For the mappings that really are element-dependent we should remove the tags in favor of using the requirements. Once the requirements are widely used we can do that breaking change where we pull the requirement-tags so that everything comes from the requirements object.
Removing the requirement tags does mean it is no longer possible to include specific success criteria. If you wanted to run WCAG Level A + only color contrast you'd have to turn on the color contrast rule specifically, instead of adding the tag. While if needed, we could come up with a new API to support this, I have never hard of anyone actually doing this, so I don't think there's really necessary.