Accessible Tabs Using React & Tailwind CSS
Tags: react, tailwindcss, a11y
Published: 2020-10-20 12:39:03

---
title: Accessible Tabs Using React & Tailwind CSS
published: true
description: We'll create an accessible group of tabs that are 100% customizable using TailwindCSS.
tags: [react, tailwind, a11y]
---

We're going for tabs with automatic activation. This means a tab panel will be revealed as soon as it's respective tab receives focus either by **click** or by using the **arrow keys**.

We want to re-use the tabs functionality in many places, with many different styles. So the tab component must:
- Be re-usable.
- Be completely unstyled.
- Integrate well with Tailwind CSS.

Requirements for accessibility [From W3](https://www.w3.org/TR/wai-aria-practices/#tabpanel):

- `Tab`: When focus moves into the tab list, places focus on the active tab element.
- When focus is on a tab element in a horizontal tab list:
  - `Left Arrow`: moves focus to the previous tab. If focus is on the first tab, moves focus to the last tab.
  - `Right Arrow`: Moves focus to the next tab. If focus is on the last tab element, moves focus to the first tab.
- When focus is on a tab element in a vertical tab list:
  - `Up Arrow`: moves focus to the previous tab. If focus is on the first tab, moves focus to the last tab.
  - `Down Arrow`: Moves focus to the next tab. If focus is on the last tab element, moves focus to the first tab.
- When focus is on a tab in a tablist with either horizontal or vertical orientation:
  - `Space` or `Enter`: Activates the tab.
  - `Home`: Moves focus to the first tab.
  - `End`: Moves focus to the last tab.


## Funk

I've created a package called Funk, which contains a set of components to create Tabs.

```
yarn add @statikly/funk
```

or

```
npm install --save @statikly/funk
```

You can then use it in such fashion:

```jsx
import React from 'react'
import { TabGroup } from '@statikly/funk'

const Page = () => {
  return (
    <div className="h-screen w-screen flex flex-col justify-center items-center">
      <TabGroup numTabs={3} direction={TabGroup.direction.HORIZONTAL}>
        <TabGroup.TabList>
          <TabGroup.Tab
            index={0}
            className="h-12 px-12 transition-colors duration-150"
            activeClassName="bg-black text-white"
            inactiveClassName="text-black"
          >
            Tab 1
          </TabGroup.Tab>
          <TabGroup.Tab
            index={1}
            className="h-12 px-12 transition-colors duration-150"
            activeClassName="bg-black text-white"
            inactiveClassName="text-black"
          >
            Tab with input
          </TabGroup.Tab>
          <TabGroup.Tab
            index={2}
            className="h-12 px-12 transition-colors duration-150"
            activeClassName="bg-black text-white"
            inactiveClassName="text-black"
          >
            Tab 3
          </TabGroup.Tab>
        </TabGroup.TabList>
        <TabGroup.TabPanel
          index={0}
          className="p-16 transition-all transform h-64"
          activeClassName="opacity-100 duration-500 translate-x-0"
          inactiveClassName="absolute opacity-0 -translate-x-2"
        >
          Content 1
        </TabGroup.TabPanel>
        <TabGroup.TabPanel
          index={1}
          className="p-16 transition-all transform h-64 flex flex-col"
          activeClassName="opacity-100 duration-500 translate-x-0"
          inactiveClassName="absolute opacity-0 -translate-x-2"
        >
          <label className="font-semibold mb-1" htmlFor="input">
            Input
          </label>
          <input
            id="input"
            type="text"
            className="border border-gray-400 px-8 h-12"
            placeholder="Focus me!"
          />
        </TabGroup.TabPanel>
        <TabGroup.TabPanel
          index={2}
          className="p-16 transition-all transform h-64"
          activeClassName="opacity-100 duration-500 translate-x-0"
          inactiveClassName="absolute opacity-0 -translate-x-2"
        >
          Content 3
        </TabGroup.TabPanel>
      </TabGroup>
      <button className="mt-12 h-12 px-12 bg-indigo-500 text-white">
        Outside button
      </button>
    </div>
  )
}
```

Check out the Codesandbox and give it a whirl!

{% codesandbox funk-example-uw048 %}

Prefer to get the code yourself or take a look under the hood? [Check out the repo here!](https://github.com/RobertBroersma/funk)