Skip to main content

Tabs

Multiple tab groups are possible on the same page. Use data attributes and IDs to link each tab with its content, allowing the HTML markup to be mostly independent of the functional aspect.

Style and functionality can be easily modified for your project (e.g., to create vertical tabs or other variations).

The focus is also trapped within the tabs, enabling keyboard navigation using the left/right arrow keys.

Demo

Installation

Import the function into the JavaScript file of your project

import { Tabs } from "@overdog/fn"

Create and initialize an instance

new Tabs("#tabs", {
  // options goes here
}).init()

Add the Tailwind variants to the plugins section of your config file.

If you are using multiple elements from Overdog FN that require the same variants, you only need to add them once. You can also modify the data attributes added to each function using the attributes parameter {}.

module.exports = {
   // ...
   plugins: [
      plugin(function ({ addVariant }) {
         addVariant("is-open", "&[data-fn-is-open]")
         addVariant("parent-is-open", "[data-fn-is-open] &")
      })
   ]
}

Note: Ensure that your tab IDs and data-fn-target IDs are unique if you have multiple tab groups on the same page.

Twig template Code


{# You probably want to change this array for a Craft CMS query #}
{% set contentArray = [
   { title: "First tab", content: "1 - Praesent maximus, mi a faucibus viverra." },
   { title: "Second tab", content: "2 - Praesent maximus, mi a faucibus viverra. Praesent maximus, mi a faucibus viverra." },
   { title: "Third tab", content: "3 - Praesent maximus, mi a faucibus viverra. Faucibus viverra." }
] 
%}

<div id="tabs">
   <div 
      class="flex border-b border-gray-400" 
      data-fn-tabs 
      role="tablist" 
   >
      {% for item in contentArray %}
         <button 
            class="block py-4 px-6 bg-white is-open:bg-slate-800 is-open:text-white"
            {% if loop.index is same as 1 %}data-fn-is-open{% endif %}{# open the first heading on load #}
            data-fn-tabs-heading
            data-fn-target="tab-{{ loop.index }}"
            role="tab"
            aria-selected="true" 
            aria-controls="tab-{{ loop.index }}"
         >
            {{ item.title }}
         </button>
      {% endfor %}
   </div>
   {% for item in contentArray %}
      <div 
         class="hidden overflow-hidden py-4 is-open:block"
         {% if loop.index is same as 1 %}data-fn-is-open{% endif %}{# open the first content on load #}
         data-fn-tabs-content
         id="tab-{{ loop.index }}" 
         role="tabpanel" 
         aria-labelledby="tab-{{ loop.index }}"
      >
       {{ item.content }}
      </div>
   {% endfor %}
</div>

Options