I'm setting up a tabbed content section in my page using a script that follows the following syntax:
<!-- Clickable tab links -->
<ul class="js-tablist">
<li id="tab1" class="js-tab active"><a href="#tabpanel1">Tab 1</a></li>
<li id="tab2" class="js-tab"><a href="#tabpanel2">Tab 2</a></li>
<li id="tab3" class="js-tab"><a href="#tabpanel3">Tab 3</a></li>
</ul>
<!-- Tab panels -->
<div id="tab-set" class="js-tabpanel-group">
<section id="tabpanel1" class="js-tabpanel">__CONTENT__</section>
<section id="tabpanel2" class="js-tabpanel">__CONTENT__</section>
<section id="tabpanel3" class="js-tabpanel">__CONTENT__</section>
</div>
I will be setting various ARIA roles (role="tablist"
, role="tab"
, role="tabpanel"
, etc) on this structural markup via javascript (since if there's no scripting then there are no tabs) but I'm unsure quite where to place my ‘aria-controls’ attributes. Should they go on the <li>
element or on its <a>
child element? Or does it not matter? Indeed, the same question could be asked about role="tab"
and tabindex="0"
-- should these things go on the list item or the anchor?
The aria-controls attribute identifies the element (or elements) whose contents or presence are controlled by the element on which the attribute is set, regardless of what type of interaction initiates the impacted behavior.
In a tablist, aria-selected is used on a tab to indicate the currently-displayed tabpanel . The selected tab in a tablist should have has its aria-selected="true" set. All inactive tabs in the tablist should have aria-selected="false" set.
The aria-expanded attribute is set on an element to indicate if a control is expanded or collapsed, and whether or not its child elements are displayed or hidden.
Put aria-controls
on the item that gets role="tab"
.
aria-controls
is what creates the relationship between a tab and its panel. See the third bullet in the description for aria-controls
from the spec: https://www.w3.org/TR/wai-aria-1.1/#aria-controls
To answer your follow-on question, put the role="tab"
on the <a href>
since that is already primed to receive keyboard focus and be actionable by the browser. That also means you won't need to use tabindex
at all.
Consider also throwing a role="presentation"
on the <li>
elements and role="tablist"
on the <ul>
(especially since you rendering the <li>
inert with role="presentation"
).
Be prepared to also manage arrow key navigation, as by using the tab roles you are essentially telling an expert user that these tabs will behave like tabs in the OS, which honor arrow keys to switch between tabs.
Additional resources worth checking out:
After all this, please test it in screen readers to make sure it behaves as you expect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With