HTML

Tabs (ARIA tablist pattern)

admin by @admin ADMIN
1h ago
May 31, 2026
Public
0 0 up · 0 down Sign in to vote
The accessible tab pattern: a `role="tablist"` container, each tab as `role="tab"`, panels as `role="tabpanel"`. `aria-selected` + `aria-controls` link them and announce state.
HTML
Raw
<div class="tabs">
    <div role="tablist" aria-label="Account settings">
        <button role="tab" id="t1" aria-controls="p1" aria-selected="true"  tabindex="0">Profile</button>
        <button role="tab" id="t2" aria-controls="p2" aria-selected="false" tabindex="-1">Security</button>
        <button role="tab" id="t3" aria-controls="p3" aria-selected="false" tabindex="-1">Billing</button>
    </div>

    <div role="tabpanel" id="p1" aria-labelledby="t1">
        Profile fields…
    </div>
    <div role="tabpanel" id="p2" aria-labelledby="t2" hidden>
        Security fields…
    </div>
    <div role="tabpanel" id="p3" aria-labelledby="t3" hidden>
        Billing fields…
    </div>
</div>

<script>
const tabs = document.querySelectorAll('[role="tab"]');
tabs.forEach((tab, i) => {
    tab.addEventListener('click', () => activate(tab));
    tab.addEventListener('keydown', (e) => {
        if (e.key === 'ArrowRight') activate(tabs[(i + 1) % tabs.length]);
        if (e.key === 'ArrowLeft')  activate(tabs[(i - 1 + tabs.length) % tabs.length]);
    });
});
function activate(tab) {
    tabs.forEach(t => {
        const sel = t === tab;
        t.setAttribute('aria-selected', sel);
        t.setAttribute('tabindex',      sel ? '0' : '-1');
        document.getElementById(t.getAttribute('aria-controls')).hidden = !sel;
    });
    tab.focus();
}
</script>
Tags

Save your own code snippets

Create a free account and build your private vault. Share publicly whenever you want.