DEV Community

Robert
Robert

Posted on

Accessible Tabs Using React & Tailwind CSS

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:

  • 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 
Enter fullscreen mode Exit fullscreen mode

or

npm install --save @statikly/funk 
Enter fullscreen mode Exit fullscreen mode

You can then use it in such fashion:

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> ) } 
Enter fullscreen mode Exit fullscreen mode

Check out the Codesandbox and give it a whirl!

Prefer to get the code yourself or take a look under the hood? Check out the repo here!

Top comments (1)

Collapse
 
p014ri5 profile image
Prasad Narkhede

Thanks for this, helped a ton!