Skip to content

aria-required-children "unallowed" message not actionable #3842

@dbjorge

Description

@dbjorge

Product

axe-core

Product Version

4.6.1

Latest Version

  • I have tested the issue with the latest version of the product

Issue Description

The message for the unallowed type of aria-required-children failure introduced in axe-core 4.5 via #3597 is a little confusing for folks that aren't already familiar with ARIA ownership rules because the message doesn't summarize why the given children would be disallowed. We think this would be improved by updating the message to be more clear that the reason the children are disallowed is that they have roles which are disallowed, and what those roles are.

We understand that not including the roles in the message was an intentional choice to avoid the complexity of cases with children that don't have roles, but we'd like to request revisiting that choice - we think the amount of complexity this would add to the message calculation would be a worthwhile tradeoff to avoid user confusion.

Expectation

The message should contain enough information for a user unfamiliar with the rule to understand why it's being triggered in a given specific case. For example:

Element with role "menu" cannot have children with roles img,link

or:

Element with role "list" cannot have children visible to screen readers with no role

Actual

The message currently reads:

Element has children which are not allowed (see related nodes)

...without explaining what causes the children to be not allowed.

How to Reproduce

Codepen containing examples of each of the 6 cases suggested below, along with an embedded working example of the suggested output below

Additional context

Suggested new message templates to replace the rule's current "unknown" template:

"unallowedRoleSingular": "Element with role \"${data.role}\" cannot have child with role ${data.unallowedRoles}",
"unallowedRolePlural": "Element with role \"${data.role}\" cannot have children with roles ${data.unallowedRoles}",
"unallowedNoRoleSingular": "Element with role \"${data.role}\" cannot have child visible to screen readers with no role",
"unallowedNoRolePlural": "Element with role \"${data.role}\" cannot have children visible to screen readers with no role",
"unallowedMixedRoleSingular": "Element with role \"${data.role}\" cannot have children visible to screen readers with no role or with role ${data.unallowedRoles}",
"unallowedMixedRolePlural": "Element with role \"${data.role}\" cannot have children visible to screen readers with no role or with roles ${data.unallowedRoles}"

...and suggested aria-required-children-evaluate.js snippet (to replace current L87-89) to populate the necessary data/messageKey:

    const unallowedRoles = unallowed.map(({ role }) => role).filter(role => role !== null);
    const unallowedNullRoleCount = unallowed.length - unallowedRoles.length;
    
    let messageKey;
    if(unallowedRoles.length === 0) {
      if (unallowedNullRoleCount === 1) {
        messageKey = 'unallowedNoRoleSingular';
      } else {
        messageKey = 'unallowedNoRolePlural';
      }
    } else if (unallowedRoles.length === 1) {
      if (unallowedNullRoleCount === 0) {
        messageKey = 'unallowedRoleSingular';
      } else {
        messageKey = 'unallowedMixedRoleSingular';
      }
    } else { // unallowedRoles.length > 1
      if (unallowedNullRoleCount === 0) {
        messageKey = 'unallowedRolePlural';
      } else {
        messageKey = 'unallowedMixedRolePlural';
      }
    }

    this.data({
      messageKey,
      role,
      unallowedRoles,
    });
No-role terminology

The terminology "visible to screen readers" was the closest analogue I found in existing messages (aria-errormessage, aria-labelledby, button-has-visible-text, has-visible-text) for the case that would trigger an unknown failure for a no-role child here ("has a global aria property OR is focusable"). I think this is easier to understand than the current text, but it might be even more actionable to be more specific and literally tell the user that the issue is that there's a child "with global ARIA property {data.propertyName}" or "which is focusable".

I chose not to include that in this suggestion since it exploded the number of messages even further; I think if we wanted to go down that route, it might be better to separate this logical check out of aria-required-children into a separate rule which creates a separate failure per bad parent-child relationship (maybe `aria-allowed-child' or something).

Metadata

Metadata

Assignees

No one assigned

    Labels

    prA pr has been created for the issuerule metadataIssues in the rule metadata code (lib/rules)

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions