Accessible tabs: A step-by-step guide

Two people adding content into tabs

Hello there, and welcome back! Today, we’re diving into the world of tabs and how to make them accessible for everyone. Tabs are a fantastic way to organize information, letting you neatly categorize content for easy access. Ready to dive in? Let’s roll up our sleeves and get started!

Roles: Getting to know the parts

Think of roles as little name tags we give to different parts of our tabs, so everyone understands their purpose. Since there’s no default HTML element for them, we use ARIA roles like tablist, tab, and tabpanel.

  1. role="tablist": This is the container that holds all your tabs. It’s like the sign that says, “Here are your tabs!”
  2. role="tab": Each individual tab gets this role. It’s the label for a specific category or section.
  3. role="tabpanel": This is where the magic happens—where the content for each tab shows up.

Here’s a simple setup:

<div class="mytabs">
  <div role="tablist"> <!-- The container that holds all your tabs -->
    <button role="tab">France</button> <!-- Each tab stands for a different category -->
    <button role="tab">Italy</button>
    <button role="tab">Greece</button>
  </div>
  <div role="tabpanel">Paris is the capital of France.</div> <!-- Where the content for each tab appears -->
  <div role="tabpanel">Rome is the capital of Italy.</div>
  <div role="tabpanel">Athens is the capital of Greece.</div>
</div>
Pro tip: If your tabs are stacked vertically, let your customers know by setting aria-orientation="vertical". The default is horizontal.
<div class="mytabs">
  <div role="tablist" aria-orientation="vertical"> <!-- Tells your customers that the tabs are vertically stacked -->
    <button role="tab">France</button>
    <button role="tab">Italy</button>
    <button role="tab">Greece</button>
  </div>
  <div role="tabpanel">Paris is the capital of France.</div>
  <div role="tabpanel">Rome is the capital of Italy.</div>
  <div role="tabpanel">Athens is the capital of Greece.</div>
</div>

Linking tabs and content

Now, let’s connect each tab to its content, kind of like pairing socks. We use aria-controls and id to make sure each tab knows which content it’s responsible for showing.

<div class="mytabs">
  <div role="tablist">
    <button role="tab" aria-controls="tabpanel-1">France</button> <!-- Unique IDs help link tabs to their content -->
    <button role="tab" aria-controls="tabpanel-2">Italy</button>
    <button role="tab" aria-controls="tabpanel-3">Greece</button>
  </div>
  <div role="tabpanel" id="tabpanel-1">Paris is the capital of France.</div> <!-- The ID should match the corresponding tab's aria-controls -->
  <div role="tabpanel" id="tabpanel-2">Rome is the capital of Italy.</div>
  <div role="tabpanel" id="tabpanel-3">Athens is the capital of Greece.</div>
</div>

To ensure the right tab’s content is displayed, use aria-labelledby in the tabpanel and link it back to the tab’s id.

<div class="mytabs">
  <div role="tablist">
    <button role="tab" aria-controls="tabpanel-1" id="tab-1">France</button> <!-- Unique IDs for each tab -->
    <button role="tab" aria-controls="tabpanel-2" id="tab-2">Italy</button>
    <button role="tab" aria-controls="tabpanel-3" id="tab-3">Greece</button>
  </div>
  <div role="tabpanel" id="tabpanel-1" aria-labelledby="tab-1">Paris is the capital of France.</div> <!-- Match aria-labelledby to the tab's ID -->
  <div role="tabpanel" id="tabpanel-2" aria-labelledby="tab-2">Rome is the capital of Italy.</div>
  <div role="tabpanel" id="tabpanel-3" aria-labelledby="tab-3">Athens is the capital of Greece.</div>
</div>

Highlight your active tab

The aria-selected attribute is like a highlighter, showing which tab is currently active. This makes it clear to everyone which content is being displayed.

Make sure only the active tab has aria-selected="true", and use tabindex="-1" on inactive tabs so your customers don’t accidentally tab into them.

<div class="mytabs">
  <div role="tablist">
    <button role="tab" aria-controls="tabpanel-1" id="tab-1" aria-selected="true">France</button> <!-- Mark the active tab with aria-selected="true" -->
    <button role="tab" aria-controls="tabpanel-2" id="tab-2" aria-selected="false" tabindex="-1">Italy</button>
    <button role="tab" aria-controls="tabpanel-3" id="tab-3" aria-selected="false" tabindex="-1">Greece</button>
  </div>
  <div role="tabpanel" id="tabpanel-1" aria-labelledby="tab-1">Paris is the capital of France.</div>
  <div role="tabpanel" id="tabpanel-2" aria-labelledby="tab-2">Rome is the capital of Italy.</div>
  <div role="tabpanel" id="tabpanel-3" aria-labelledby="tab-3">Athens is the capital of Greece.</div>
</div>

Keyboard-friendly navigation

Let’s make sure everyone can navigate easily:

  1. TAB: Moves focus to the tab container.
  2. Arrow Keys: Lets users move between tabs. Left (or up) goes to the previous tab, right (or down) goes to the next one.
  3. Enter/Space Keys: Activates the tab and displays the content.

Color contrast

Last but not least, ensure your tabs and content have good color contrast. This makes everything easier to read and more accessible. Check out “The Essential Guide to Inclusive Font” for more tips on color contrast.

Conclusion

And there you have it! With these steps, your tabs are not only functional and stylish but also accessible to everyone. Thanks for reading, and happy coding!