In this tutorial, we’ll go over how to create SEO-friendly tabs using flex and jQuery.
Our code will be divided into three parts.
HTML Code
First, the HTML code — the foundation we start with:
<div class="tabs" data-tabs="name"> <ul class="tab-items"> <li class="tab__item active" data-tab-item="tab-item-1"> Tab 1 </li> <li class="tab__item" data-tab-item="tab-item-2"> Tab 2 </li> <li class="tab__item" data-tab-item="tab-item-3"> Tab 3 </li> </ul> <div class="tab-contents"> <div class="tab__content active" data-tab-content="tab-item-1"> Contents of Tab 1 </div> <div class="tab__content" data-tab-content="tab-item-2"> Contents of Tab 2 </div> <div class="tab__content" data-tab-content="tab-item-3"> Tab content 3 </div> </div> </div>
Roughly speaking, our code consists of three sections:
- A wrapper for the tab group, defined by the data attribute
data-tabs. - The tabs themselves. Each tab has its own identifier defined by
data-tab-item. This value must match one of thedata-tab-contentattributes in the content blocks. - The tab content blocks, wrapped in a container with the class
tab-contents. Each content block has adata-tab-contentattribute, which must match one of the tab item values. These attributes are used to map which tab displays which content.
CSS Code
Second, compiled SCSS in CSS using BEM naming convention:
/** Tabs */
.tabs .tab-items {
position: relative;
display: inline-flex;
list-style: none;
margin: 0;
border-bottom: 1px solid #e1e1e1;
padding: 0 25px; }
.tabs .tab__item {
position: relative;
top: 1px;
color: #222222;
font-weight: bold;
font-size: 18px;
text-align: center;
letter-spacing: 1px;
border: 1px solid #e1e1e1;
border-right: none;
background-color: #ebebeb;
padding: 10px 20px;
cursor: pointer; }
.tabs .tab__item.active {
color: #158100;
border-top: 4px solid #158100;
border-bottom: none;
background-color: #fff;
cursor: default; }
.tabs .tab__item:hover {
color: #158100; }
.tabs .tab__item:last-child {
border-right: 1px solid #e1e1e1; }
.tabs .tab__content {
display: none; }
.tabs .tab__content.active {
display: block; }Key components in the code above:
tabs— the main wrapper class for the entire tab componenttab-items— the container for the tab headerstab-contents— the container for tab contenttab__item— individual tab itemtab__content— the content section for each tab
The flex-based implementation of the tabs is done in this part:
.tabs .tab-items {
position: relative;
display: inline-flex;
list-style: none;
margin: 0;
border-bottom: 1px solid #e1e1e1;
padding: 0 25px; }That is, where we use display: inline-flex.
JavaScript Code
Third, our JavaScript code:
jQuery(document).ready(function($)
{
function siteTabs(tab)
{
var $Tabs = jQuery('[data-tabs="' + tab + '"]');
if($Tabs.length)
{
$Tabs.find('[data-tab-item]').click(function(e){
e.preventDefault();
$Tabs.find('[data-tab-item]').map(function(i, o){
jQuery(o).removeClass('active');
});
jQuery(this).addClass('active');
$Tabs.find('[data-tab-content]').map(function(i, o){
jQuery(o).removeClass('active');
});
$Tabs.find('[data-tab-content="' + jQuery(this).data('tab-item') + '"]').addClass('active');
});
}
}
siteTabs('name');
});To avoid overcomplicating things with a jQuery plugin (though we’ll publish an article on that later!), our tab component is implemented as a simple function called siteTabs(), which accepts a single parameter — the name of the tab group.
Let’s break down the function above.
We start by finding all tabs with the name specified in the tab variable:
var $Tabs = jQuery('[data-tabs="' + tab + '"]');If tabs are found, we proceed to attach a click event handler to each tab item:
$Tabs.find('[data-tab-item]').click(function(e){
/* … */
});When a tab is clicked:
$Tabs.find('[data-tab-item]').map(function(i, o){
jQuery(o).removeClass('active');
});
jQuery(this).addClass('active');We loop through all tab items and remove the active class. Then we add the class to the tab that was just clicked.
Next, we do the same for the tab content blocks:
$Tabs.find('[data-tab-content]').map(function(i, o){
jQuery(o).removeClass('active');
});
$Tabs.find('[data-tab-content="' + jQuery(this).data('tab-item') + '"]').addClass('active');To determine which tab content to show, we get the data-tab-item value from the clicked tab, find the corresponding data-tab-content block, and add the active class to it.
A working example of this implementation can be found in this tutorial.
