Reputation: 2044
I have an accordion that is rendered using van11y-accessible-accordion-aria
The markup outputs as:
<div className="c-accordion__items js-accordion accordion" data-accordion-cool-selectors="1" aria-multiselectable="true" role="tablist" id="z3j2diubs8r" data-hashaccordion-id="3o3nlqickh">
<!-- note role="tablist" above -->
<div className="c-accordion__item">
<h2 className="c-accordion__title accordion__title">
<button className="js-accordion__header accordion__header" role="tab" id="accordionz3j2diubs8r_tab1" aria-controls="accordionz3j2diubs8r_panel1" aria-selected="false" type="button" data-hashaccordion-id="3o3nlqickh" aria-expanded="false">
<!-- note role="tab" above -->
The Why
</button>
</h2>
<div className="c-accordion__item-components js-accordion__panel accordion__panel" role="tabpanel"
aria-labelledby="accordionz3j2diubs8r_tab1" id="accordionz3j2diubs8r_panel1" data-hashaccordion-id="3o3nlqickh"
aria-hidden="true">
<div className="c-accordion__item-content">
<p>Duis vel nibh at velit scelerisque suscipit. Donec vitae sapien ut libero venenatis faucibus. Quisque ut
nisi. Ut non enim eleifend felis pretium feugiat. Nulla sit amet est.
</p>
</div>
</div>
</div>
</div>
When I test this for accessibility using Lighthouse in Chrome, I am getting these messages
Elements with an ARIA [role] that require children to contain a specific [role] are missing some or all of those required children. Some ARIA parent roles must contain specific child roles to perform their intended accessibility functions. Learn more.
[role]s are not contained by their required parent element Some ARIA child roles must be contained by specific parent roles to properly perform their intended accessibility functions. Learn more.
The learn more links goes to https://web.dev/aria-required-children and shown below is a code example that they suggest.
... and there it implies that having role="tablist"
as the parent and then role="tab"
for the child.
In my code posted in this question, I seem to have the proper markup as compared to the example from https://web.dev/aria-required-children
So I am at a loss as to why this is failing the accessibility check.
Upvotes: 3
Views: 3531
Reputation: 24865
role="tab"
must be a direct descendant (or contained within an element with no semantic meaning) of a role="tablist"
element. To be fair this is really not clear in the WAI-ARIA spec but I have hit this issue myself before. (you can use aria-owns
to make the association but that is more for if the tabs sit outside the tablist
element)
Because your <button>
is wrapped in a <h2>
this breaks the pattern.
I have tested it and it appears to work in JAWS and NVDA, but just to be safe (as there are loads of screen readers and some of them may not like your implementation) I would make a minor adjustment.
Remove the <h2>
that surrounds the <button>
is one option and probably the one I would recommend. It doesn't make much sense to have multiple <h2>
elements on a widget anyway and instead you should use a heading above the tabs you have created for the section.
A second option is to make the <h2>
function like a button, but that would mean adding your own event handlers, focus indicators and tabindex="0"
to make it focusable. That way you can move the role="tab"
onto the <h2>
itself, which removes the semantic meaning but retains the ability to navigate to it in a screen reader.
I personally am not a fan of the second option but I can see why some people may choose to do that.
One other thing I would suggest is to put the tabs
and the tabpanel
s inside <ul>
and <li>
.
For screen readers that don't support tablist
this means a user still gets an announcement of "1 out of 3 options" etc. So it makes it easier to understand they have options.
Also it is recommended that each tabpanel
has a tabindex="0"
to aid navigation once a tab has been selected. This is one of those very rare circumstances where making a non-interactive element focusable is encouraged.
You may find this W3 page on tab best practices useful.
Upvotes: 3