Accessibility issues for children elements of tablist

1.4k Views Asked by At

I am trying to solve the accessibility issue discovered by axe tools for tablist.

In our case tabs in a tablist are separated by the vertical separator with an appropriate role and aria-orientation. However the tool says that role=separator is not allowed to be inside of element with role=tablist.

Ensures elements with an ARIA role that require child roles contain them

The code looks as following:

<div role="tablist" aria-orientation="horizontal">

<button id="tab-0" aria-controls="panel-0" type="button" role="tab" tabindex="0" aria-selected="true">One</button>

<div class="vertical-separator">
  <div class="tab-separator role="separator" aria-orientation="vertical"></div>
</div>

<button id="tab-1" aria-controls="panel-1" type="button" role="tab" tabindex="-1" aria-selected="false">Disabled</button>

</div>

What is a way to satisfy the accessibility rule? As a tool's proposal there are two ways:

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

Element has no aria-busy="true" attribute

But none of them is fitting

1

There are 1 best solutions below

0
slugolicious On

If you want to nit-pick, one could argue that axe is wrong with that error.

The tablist role says that "Required Owned Elements" must have a role of tab. It does not really say that only tab roles can be children.

For example, the spec for <ul> says:

Content model:
Zero or more <li> and script-supporting elements.

That is, it specifically says that child elements of a <ul> must only be <li> elements (or scripting elements).

The "Required Owned Elements" section of roles is not as specific. It does not say that only certain child elements are allowed but rather, in order for a child element to be considered owned by the parent, it must have a specific role.

In this case, in order for a child element to be owned by the tablist, it must have a role of tab. If a child element does not have that role, then it's not considered owned by the tablist. Does that mean a tablist cannot have child elements without a tab role? That's where it gets iffy. It doesn't really say that although I'm sure it's a good idea.

Even the URL for "Required Owned Elements" is called "#mustContain". Meaning, it must contain a tab child. But the URL is not called "#mustOnlyContain".

The tablist pattern says:

Each element that serves as a tab has role tab and is contained within the element with role tablist.

Again, this doesn't say that all child elements must be a tab, but only those child elements with a role of tab will be considered a tab and owned by the tablist.

When a tablist is surfaced to assistive technology, such as a screen reader, it will look at all the child elements of the tablist that have a role of tab and that will be the count of the number of tabs. The screen reader will say "[tab label], tab, 3 of 4". Any child that does not have a role of tab will not be included in that count.

Now, with all that being said, I would still encourage that all child elements have a role of tab, but I'm not sure it really breaks the rules if you don't.

In your particular case, it might be better to use CSS :after on the tab button to add a vertical separator rather than the separator being a separate DOM element.

The tablist example in the design pattern has a gap between each tab button. That gap is done with CSS on the button rather than a separate gap DOM element.