Avoid tab groups
Tab groups are a sub-par solution used in a couple of scenarios:
- A page has become bloated with content and the designer seeks to condense even more information into a tighter space.
- It’s also possible a product owner still believes it’s the year 1999 and people don’t know how to scroll.
Either way, it’s about trying to cram low quality content into a page until it becomes a high quality experience, which is not a good plan.
Why tab groups are problematic
- Many people who use a screenreader don’t know how to operate a tab group with the arrow keys and can miss parts of the content.
- It requires the screenreader user to repeatedly parse the content to consume it.
- Interaction rates will be exceedingly low for anything but the first tab panel (like a carousel).
- It hides content from the user by default and not everyone will notice or know how it works.
- If users need to compare information they cannot
What to do instead
Rather than cramming more content into the page, consider other designs such as:
- Breaking the page into more concise sections with tight copywriting
- Putting content inside expander/accordions
- Using separate pages
Wait, then why are you using tabs on this site?
- See above: The page has become bloated with content and the designer seeks to condense even more information into a tighter space. The information in the tabs is largely the same and not something the user needs to compare, so there’s no loss of functionality.
Code examples
- More details and working examples
- You can also use radio buttons as controls. This will be easier to understand for screenreader users (as is done with this website’s tabs).
- Note: an
aria-selected
state is explicity required as some screenreaders will assume the tab is selected unless delaredfalse
.
Use semantic HTML where possible
<div class="tabs">
<div role="tablist">
<button role="tab"
aria-selected="true"
aria-controls="alpha-tab"
id="alpha">
Alpha
</button>
<button role="tab"
aria-selected="false"
aria-controls="bravo-tab"
id="bravo"
tabindex="-1">
Bravo
</button>
<button role="tab"
aria-selected="false"
aria-controls="charlie-tab"
id="charlie"
tabindex="-1">
Charlie
</button>
</div>
<div role="tabpanel"
id="alpha-tab"
aria-labelledby="alpha"
tabindex="0">
<p>Alpha is the first letter of the NATO alphabet</p>
</div>
<div role="tabpanel"
id="bravo-tab"
aria-labelledby="bravo"
tabindex="0">
<p>Bravo is the second letter of the NATO alphabet</p>
</div>
<div role="tabpanel"
id="charlie-tab"
aria-labelledby="charlie"
tabindex="0">
<p>Charlie is the best letter of the NATO alphabet</p>
</div>
</div>