AllieTabs

A WCAG2.1 compliant tab component

Template

<div data-tabs>
    <ul role="tablist">
        <li role="presentation">
            <a role="tab" href="#tab1" aria-controls="tab1">
                Tab one
            </a>
        </li>
    </ul>
    <div role="tabpanel" id="tab1">
        ... content
    </div>
</div>

Required attributes are

  • role="tablist" on the UL tag containing the tabs
  • role="presentation" on the LI elements
  • role=tab on the same page links
  • aria-controls refers to the ID of the corresponding tabpanel
  • role=tabpanel identifies the tabpanel

The code will add aria-hidden, aria-selected and tabindex
but you can also choose to add these yourself to control which panel is opened by default.

controls

Keyboard controls

  • Tab - only the active tab is in the tab order. The user reaches the tabbed panel component by pressing the tab key until the active tab title receives focus.
  • Left Arrow - with focus on a tab, pressing the left arrow will move focus to the previous tab in the tab list and activate that tab. Pressing the left arrow when the focus is on the first tab in the tab list will move focus and activate the last tab in the list.
  • Right Arrow - with focus on a tab, pressing the right arrow will move focus to the next tab in the tab list and activate that tab. Pressing the right arrow when the focus is on the last tab in the tab list will move focus to and activate the first tab in the list.
  • Up arrow - behaves the same as left arrow in order to support vertical tabs
  • Down arrow - behaves the same as right arrow in order to support vertical tabs
  • Home - with focus on a tab, moves the focus to the first tab.
  • End - with focus on a tab, moves the focus to the last tab.

URL

You, or the user, can control which tab is opened by default by using the tabpanel id as fragment in the URL.

Usage

Code

Once your HTML has all required attributes, you can initialise the tabs on two ways.

Automatic: place the data-tabs attribute on the outer wrapper.

Manual: initialise the tabs as follows:

@param {Element} elem
@param {Object} [options]

allieTabs.init(elem, options)

Overrides

You can override the changeTab and handleKeyboardInput functions by providing them in the options object.

For instance:

allieTabs.init(elem, {handleKeyboardInput: function(e: Event, tabs: Element[]) {})

Styling

When using the automatic initialisation a class allietabs will be placed on the outer wrapper when the code has been executed successfully.

Using the manual method, you can provide your custom class in the options attribute

allieTabs.init(elem, {class: 'my-custom-class'})

Fallback

Styling based on the added wrapper-class allows for fallback functionality in case something went wrong or in case javascript is not available.
In which case the tabs will function as standard same page links.

Fallback example

Template

<div data-tabs>
    <ul role="tablist">
        <li role="presentation">
            <a role="tab" href="#tab1" aria-controls="tab1">
                Tab one
            </a>
        </li>
    </ul>
    <div role="tabpanel" id="tab1">
        ... content
    </div>
</div>

Required attributes are

  • role="tablist" on the UL tag containing the tabs
  • role="presentation" on the LI elements
  • role=tab on the same page links
  • aria-controls refers to the ID of the corresponding tabpanel
  • role=tabpanel identifies the tabpanel

The code will add aria-hidden, aria-selected and tabindex
but you can also choose to add these yourself to control which panel is opened by default.

controls

Keyboard controls

  • Tab - only the active tab is in the tab order. The user reaches the tabbed panel component by pressing the tab key until the active tab title receives focus.
  • Left Arrow - with focus on a tab, pressing the left arrow will move focus to the previous tab in the tab list and activate that tab. Pressing the left arrow when the focus is on the first tab in the tab list will move focus and activate the last tab in the list.
  • Right Arrow - with focus on a tab, pressing the right arrow will move focus to the next tab in the tab list and activate that tab. Pressing the right arrow when the focus is on the last tab in the tab list will move focus to and activate the first tab in the list.
  • Up arrow - behaves the same as left arrow in order to support vertical tabs
  • Down arrow - behaves the same as right arrow in order to support vertical tabs
  • Home - with focus on a tab, moves the focus to the first tab.
  • End - with focus on a tab, moves the focus to the last tab.

URL

You, or the user, can control which tab is opened by default by using the tabpanel id as fragment in the URL.

Usage

Code

Once your HTML has all required attributes, you can initialise the tabs on two ways.

Automatic: place the data-tabs attribute on the outer wrapper.

Manual: initialise the tabs as follows:

@param {Element} elem
@param {Object} [options]

allieTabs.init(elem, options)

Overrides

You can override the changeTab and handleKeyboardInput functions by providing them in the options object.

For instance:

allieTabs.init(elem, {handleKeyboardInput: function(e: Event, tabs: Element[]) {})

Styling

When using the automatic initialisation a class allietabs will be placed on the outer wrapper when the code has been executed successfully.

Using the manual method, you can provide your custom class in the options attribute

allieTabs.init(elem, {class: 'my-custom-class'})

Fallback

Styling based on the added wrapper-class allows for fallback functionality in case something went wrong or in case javascript is not available.
In which case the tabs will function as standard same page links.