Lesson 12 of 30
Tabs and accordions are both progressive disclosure — show one thing, hide the rest, expose which is which — but they use different ARIA shapes and a div-with-onClick version of either is invisible to a screen reader.
12 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 3
In an accessible tablist, why does only the currently active tab have tabindex="0" while the rest have tabindex="-1"?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
Tabs and accordions solve the same underlying problem — showing a limited amount of content at once while keeping the rest available — but they're different widgets with different ARIA shapes, because the relationship between the parts is different.
Tabs are mutually exclusive: exactly one tab is selected at a time, and selecting a new one hides the previous panel entirely. Accordions are independent: each section can be expanded or collapsed on its own, and (usually) more than one can be open at once. That difference in relationship is exactly what drives the different markup each pattern needs.
<!-- Tabs: mutually exclusive, roving tabindex -->
<div role="tablist" aria-label="Account settings">
<button role="tab" aria-selected="true" aria-controls="panel-profile" id="tab-profile" tabindex="0">Profile</button>
<button role="tab" aria-selected="false" aria-controls="panel-billing" id="tab-billing" tabindex="-1">Billing</button>
</div>
<div role="tabpanel" id="panel-profile" aria-labelledby="tab-profile">...</div>
<div role="tabpanel" id="panel-billing" aria-labelledby="tab-billing" hidden>...</div>
<!-- Accordion: independent, each trigger is its own Tab stop -->
<h3>
<button aria-expanded="true" aria-controls="section-shipping">Shipping details</button>
</h3>
<div id="section-shipping" aria-labelledby="trigger-shipping">...</div>
The tabs pattern wraps everything in role="tablist", with each clickable header carrying role="tab". aria-selected marks the one currently active tab, and aria-controls points at that tab's matching role="tabpanel", which in turn points back with aria-labelledby — the panel's accessible name comes from its tab, not a separate heading. Because only one tab can be selected at a time, tabs reuse the roving-tabindex pattern: only the active tab has tabindex="0" and is a stop in the page's normal Tab order, while the rest sit at tabindex="-1"; the arrow keys (not Tab) move the roving focus and selection between tabs.
Accordions are simpler. Each trigger is typically a real <button> (often wrapped in a heading for outline purposes) with aria-expanded reflecting open or closed, and aria-controls pointing at the content region it reveals. That region usually carries aria-labelledby pointing back at the trigger. There's no shared roving-tabindex requirement here — since sections open and close independently rather than mutually excluding each other, every trigger is just a normal Tab stop on its own.
<div>-based tab or accordion with onClick and correct visual show/hide behavior is completely opaque to a screen reader — it looks and works fine for a sighted mouse user, but without role, aria-selected/aria-expanded, and aria-controls, a screen reader user gets no indication anything is a tab, is expandable, or has a hidden/visible state at all.role="tablist".hidden attribute or equivalent), not just visually hidden with opacity:0 or height:0 — a visually-hidden-but-still-in-the-DOM panel can still be reachable by assistive tech navigation, which is confusing when its tab isn't even selected.aria-label if there's no visible text.aria-controls is a relationship, not an announcement — it doesn't substitute for aria-selected or aria-expanded; all three attributes are doing different, necessary jobs."What's the difference between how you'd build accessible tabs versus an accessible accordion?" is a real question that tests whether a candidate understands ARIA roles are chosen based on the actual relationship between elements (mutually exclusive vs. independent), not copy-pasted from the nearest example.