Origami Frontend Components & Services

Readme: o-tabs

Tabs component for dividing content into meaningful sections.



The tablist, tabs and tabpanels must be identified by ARIA role attributes.

The tab elements must contain a link whose href attribute points to the ID of a tabpanel element.

The tabpanel elements must have a o-tabs__tabpanel class added to them.

This is an example of an HTML structure that o-tabs will accept:

<ul data-o-component="o-tabs" class="o-tabs" role="tablist">
    <li role="tab"><a href="#tabContent1">Tab 1</a></li>
    <li role="tab"><a href="#tabContent2">Tab 2</a></li>
    <li role="tab"><a href="#tabContent3">Tab 3</a></li>
<div id="tabContent1" class="o-tabs__tabpanel">
    Tab content 1
<div id="tabContent2" class="o-tabs__tabpanel">
    Tab content 2
<div id="tabContent3" class="o-tabs__tabpanel">
    <div>Note: first elements of each tab will get focused when it is selected. In this case, this div will receive focus.</div>
    Tab content 3

To set the initially selected tab, add an aria-selected="true" attribute to a tab element, otherwise the first tab will be selected automatically.


You can set config options declaratively by using [data-o-tabs-] prefixed data attributes.

Options consist of:

Core experience

Without the accompanying JavaScript, the tabs will receive no styling, and all tabpanels will remain visible. It's recommended that the default styling is to have each of the tabpanels displayed one below the other.

A product may choose to hide the tabs like this:

.o-tabs { display: none; }
.o-tabs--js { display: block; }


ARIA attributes will be set on elements as follows:

On init, aria-controls is added to each tab element, with value being the ID of the associated tabpanel.

On init and selected tab change these attributes are set and updated as appropriate:

These state attributes are used by the o-tabs CSS.



A o.DOMContentLoaded event can be dispatched on the document to auto-construct a o-tabs object for each element with a data-o-component="o-tabs" attribute:

document.addEventListener("DOMContentLoaded", function() {
    document.dispatchEvent(new CustomEvent('o.DOMContentLoaded'));

Auto-construction can be disabled for a specific element via another data attribute (data-o-tabs-autoconstruct="false").

Note that for browsers that do not support DOMContentLoaded (IE8 etc), the event could be polyfilled, or construction can be manually invoked:

const Tabs = require('o-tabs');
const tabsObjects = Tabs.init(document.body, {
    disablefocus: false

An array of any constructed Tabs objects will be returned.

Tabs.init(config) will not create Tabs objects for elements that already have Tabs objects constructed on them, therefore it's safe to call more than once on the same page region.


const Tabs = require('o-tabs');
const myTabs = new Tabs(document.getElementById('myTabsRootElement'), {
    disablefocus: false


The following events will be dispatched on the Tabs' root DOM element:


Tabs are indexed starting from 0.

The following API methods are provided:


o-tabs comes with either base styling, which should be used as a base for you to add your own styling. Or full styling called buttontabs; based on the buttons from o-buttons).

To apply the buttontabs styling, add a o-tabs--buttontabs class to the root element:

<ul data-o-component="o-tabs" class="o-tabs o-tabs--buttontabs" role="tablist">

or use the mixin:

@include oTabsButtonTabs;

The buttontabs style comes in two sizes that conform to the o-buttons sizes: medium and big. Medium is the default size and big can be applied by adding the class o-tabs--big.



o-tabs styles are also available via mixins. The base styles and buttontabs styles are available using the oTabs and oTabsButtonTabs mixins.

If you're using the Sass mixins, you can also theme o-tabs using the oTabsButtonTabsTheme mixin, which can be set to any of the o-buttons themes by passing the name as a parameter:

@include oTabsButtonTabsTheme($theme: 'inverse', $selector: false);

Custom themes are also supported using oTabsButtonTabsTheme and the same custom theme map as for o-buttons custom themes.

Migration Guide

Migrating from v3 to v4

This major includes the new o-colors and o-buttons, and updates the themes and sizes of button tabs.

The following changes have been made to the themes:

As well as this, the JavaScript for o-tabs now relies on String.prototype.trim. This is present in modern browsers and can be polyfilled in others.


If you have any questions or comments about this component, or need help using it, please either raise an issue, visit #ft-origami or email Origami Support.


This software is published by the Financial Times under the MIT licence.

active Origami v1
Switch component view

GitHub Repository

Install o-tabs

If using the Build Service, add o-tabs@^4.3.2 to your script and link tags. Ensure the correct brand is set with a query parameter &brand=internal.

If running a Manual Build, run npm install "o-tabs@^4.3.2".

Help & Support

o-tabs is maintained directly by the Origami team. If you have any questions about o-tabs or Origami in general, we are happy to help. 😊

Slack: #ft-origami
Email: origami.support@ft.com

Feedback / Issues

To report a bug or request features please create an issue on Github. For support or general feedback please get in touch 😊

Slack: #ft-origami
Email: origami.support@ft.com