Axe-core: aXe Coconut issue for rule: <li> elements must be contained in a <ul> or <ol>

Created on 24 Oct 2018  路  14Comments  路  Source: dequelabs/axe-core

I believe this rule is incorrect. As an example, see this semantically proper markup, which it catches as a violation:

<ul id="vt_common" role="group" aria-label="Actions">
   <li class="vt-common-item"><a class="vt-common-link" href="https://vt.edu/apply.html">Apply</a></li>
   <li class="vt-common-item"><a class="vt-common-link" href="https://vt.edu/visit.html">Visit</a></li>
   <li class="vt-common-item"><a class="vt-common-link" href="https://webapps.es.vt.edu/givingto/gift">Give</a></li>
  <li class="vt-common-item"><a class="vt-common-link" href="http://www.hokiegear.com/?_s=bm-storefront&amp;utm_source=vt_edu&amp;utm_medium=referral">Shop</a></li>
</ul>

The Aria 1.1 definition for the listitem role states:

Authors _MUST_ ensure elements with role listitem are contained in, or owned by, an element with the role list or group.

Now, I'm not sure that changing the ul to a group is a great idea, but it doesn't seem strictly improper. I'm guessing it probably was done this way to get certain screen readers to more reliably voice the label provided for it.

needs discussion rules

Most helpful comment

Great. Thanks for getting clarity on this.

All 14 comments

Have you tested this in AT to see how well it is supported? We need that data to make a decision on whether to support it in axe-core.

Well, how would you determine how well it is supported? What would be the expected behavior for these particular semantics for what particular AT? What does "accessibility-supported" mean for Deque?

To me, in this instance, it is a judgement call. Changing the role of the ul to group removes _some_ list-related affordances for _some_ screen readers, but has the advantage of causing the label assigned to the element to be surfaced more reliably. In the case cited, it was viewed as being more important that the user know what the group of navigation items they were interacting with was called than that they know how many items were in the list. With this strategy, it allows for more chunking of information than would be advisable using landmark regions. I'm not sure that was the right call, but there are subtle trade-offs for any design decision when it comes to accessibility, it seems. To get a sense of the plusses and minuses, see the results of my initial screen reader testing below.

I guess the main thing is that the strength of aXe is that it doesn't result in as many false positives (or negatives--can never remember which is which), so it is strange that it would be this opinionated here.

JAWS 18

  • IE 11

    • Doesn't announce label if you tab into the list.

    • Surfaces the number of items in a list when you enter the list. Does not surface the number of items in a group when entering a group

    • L quick key only works for lists.

    • I quick key works for navigating to listitems in lists and groups, but does not surface label.

    • Using U quick key to enter list or group does not cause label to be surfaced.

    • Bringing up a FN+CTRL+L only surfaces content of lists, but not their labels.

  • Firefox 52.9.0

    • Announces all three list items at once when you use virtual cursor to enter list.
    • Neither L nor I quick keys work for groups.
    • Entering a list with L or I quick keys does not cause the label to be surfaced
    • Bringing up a FN+CTRL+L surfaces the labels for lists, but groups don't show up.

      NVDA 2018.2.1

  • IE 11

    • Surfaces the number of items in a list when you enter the list. Does not surface the number of items in a group when entering a group
    • Surfaces label when navigating using the L or I quick keys on groups, but not on lists.
    • Surfaces label when navigating using the tab key on groups, but not on lists.
    • Does not surface the label for either groups or lists when navigating using the virtual cursor
  • Firefox 52.9.0

    • Surfaces the number of items in a list when you enter the list. Does not surface the number of items in a group when entering a group
    • Neither L nor I quick keys work for groups.
    • Entering a list with L or I quick keys does not cause the label to be surfaced
    • Surfaces label when entering a group using the K quick key. Does not surface the label when entering a list using the K quick key.

      VoiceOver/Safari on macOS High Sierra

  • Surfaces labels of both groups and lists when "Navigating web pages by" is set to "Grouping items"

  • Surfaces the number of items in lists or groups when "Navigating web pages by" is set to "Grouping items"
  • Can't navigate to groups using list navigation, as with Web Rotor or Quick Nav key navigation (VO+CMD+x)
  • When using lists navigation, as with Web Rotor or Quick Nav key navigation (VO+CMD+x), labels of lists, and the number of items in them, are surfaced.

    VoiceOver/Safari on iOS 12.0.1

  • Surfaces label for lists when left/right or up/down (when links or lists selected in the rotor) swiping

  • Does not surface labels with left/right or up/down swiping
  • Surfaces label on touch only for lists

    Talkback/Firefox on Android 8 (Samsung Galaxy S8)

  • Surfaces label on left/right swipe, whether Default or Link is selected in Context Menu

  • Surfaces label on touch for lists and groups
  • Surfaces the number of items in lists, but not in groups

And this is what I was using to test:

<h2>List with No Links</h2>
<button>focus target</button>
<p>some more text</p>
<ul aria-label="unordered list with no links">
    <li>item 1</li>
    <li>item 2</li>
    <li>item 3</li>
</ul>
<h2>Group with No Links</h2>
<button>focus target</button>
<p>some more text</p>
<ul role="group" aria-label="group override with no links">
    <li>item 1</li>
    <li>item 2</li>
    <li>item 3</li>
</ul>
<h2>List with Links</h2>
<button>focus target</button>
<p>some more text</p>
<ul aria-label="unordered list with links">
    <li><a href="a.html">item 1</a></li>
    <li><a href="b.html">item 2</a></li>
    <li><a href="c.html">item 3</a></li>
</ul>
<h2>Group with Links</h2>
<button>focus target</button>
<p>some more text</p>
<ul role="group" aria-label="group override with no links">
    <li><a href="a.html">item 1</a></li>
    <li><a href="b.html">item 2</a></li>
    <li><a href="c.html">item 3</a></li>
</ul>
<p>some text</p>
<button>focus target</button>

Thanks so much for the thorough results! It does sound pretty nuanced; I'll wait until @WilcoFiers and @dylanb get a chance to chime in, as we always discuss these things to come to a consensus before making changes in axe-core.

That said, you can read a blog post I wrote recently about Accessibility Support in axe: https://www.deque.com/blog/weve-got-your-back-with-accessibility-supported-in-axe/

Hey Rob. Thank you for reporting this issue. I struggle with this case. There certainly seems to be an accessibility issue there, when you can't use list shortcut keys, and item count doesn't seem to work. It almost seems to me like you're trying to have the list both function as a list and a landmark. Have you considered using a separate element to give the region a name, something like:

<nav aria-label="actions"><ul>
  <li><a href="">...</a></li>
</ul></nav>

Actually, in this instance, it already is in a labelled <nav>, but the labelled group was used to allow finer-grained identification within the <nav>. Basically, it is a way of avoiding excessive landmarks, while still providing context. It is possible to get both label surfacing and the list affordances by placing the <ul> in a <div> with role="group", but I wanted to avoid that. Since a <ul> is already a group, it seemed duplicative and hacky. Right now, I'm actually recommending the developer get rid of the role="group" in this instance, but it is debatable, and that is why I was objecting to aXe flagging it as an outright error.

group in the context of list is to group items within the list not to replace the list completely.

Here is the full quote from the spec

Authors SHOULD use a group to form logical collection of items in a widget such as children in a tree
widget forming a collection of siblings in a hierarchy, or a collection of items having the same container
in a directory. However, when a group is used in the context of list, authors MUST limit its children to
listitem elements. Therefore, proper handling of group by authors and assistive technologies is
determined by the context in which it is provided.

I find that quote subtle and confusing. Semantically, at least, it still seems valid to use the group role as a parent of list items, regardless of that group's parent. Evidence favoring that interpretation is that the following HTML does not trigger any errors or warnings on the Nu HTML Checker:

<!DOCTYPE html>
<html lang="en">
<head>
<title>Test</title>
</head>
<body>
<ul role="group" aria-label="group overriding unordered list">
    <li>item 1</li>
    <li>item 2</li>
    <li>item 3</li>
</ul>
</body>
</html>

Also, if you, instead, wrap the list items in a <div> with the group role whose parent is a <ul> as follows, it has the same effect in terms of screen reader support, namely, the number of list items is still not announced (at least on VoiceOver).

<ul>
  <div role="group" aria-label="group inside unordered list">
      <li>item 1</li>
      <li>item 2</li>
      <li>item 3</li>
  </div>
</ul>

And the second code snippet I provided _does_ fail the Nu HTML Checker (though I think wrongly, based on the spec), so take that for what it's worth.

Maybe it would be helpful if there was an example of where group _could_ be used as a parent of listitem elements. In the quote you provided, they give the example of a tree, but a tree doesn't contain listitem elements, but, rather, treeitem elements. Can you provide an example of a pattern where a group element contains listitem elements, as clearly seems to be allowed, by the Aria 1.1 definition for the listitem role?

Authors _MUST_ ensure elements with role listitem are contained in, or owned by, an element with the role list or group.

I believe the ARIA spec is not precise enough in the definition of listitem. It should really state:

Authors MUST ensure elements with role listitem are contained in, or owned by, an element with the role list or group and that when a group is used, it is contained or owned by an element with the role list.

@schne324 would it be possible for you to clarify this with the other members of the ARIA WG?

@dylanb I can do that. I'll post any feedback here

Relevant pull request: https://github.com/w3c/aria/pull/869

Great. Thanks for getting clarity on this.

Was this page helpful?
0 / 5 - 0 ratings