Tabs
Advanced Custom Fields
If working with ACF, you will want to utilize the following fields:
Repeater Field: tabs
Fields:
- Text:
tab_title
- WYSIWYG:
tab_content
Markup
HTML
<div class="Tabs">
<nav class="Tabs-nav">
<a href="#" class="Tabs-link is-active">Tab 1</a>
<a href="#" class="Tabs-link">Tab 2</a>
</nav><!-- //.Tabs-nav -->
<div class="Tab is-active">
Tab 1 Content
</div><!-- //.Tab -->
<div class="Tab">
Tab 2 Content
</div><!-- //.Tab -->
</div><!-- //.Tabs -->
PHP
<?php
$nav_count = 0;
$tab_count = 0;
?>
<?php if ( have_rows( 'tabs' ) ): ?>
<div class="Tabs">
<?php while( have_rows( 'tabs' ) ): the_row(); ?>
<nav class="Tabs-nav">
<a href="#" class="Tabs-link <?php echo ( $nav_count == 0 ? 'is-active': '' ); ?>"><?php the_sub_field( 'tab_title' ); ?></a>
</nav><!-- //.Tabs-nav -->
<?php $nav_count++; ?>
<?php endwhile; ?>
<?php while( have_rows( 'tabs' ) ): the_row(); ?>
<div class="Tab <?php echo ( $tab_count == 0 ? 'is-active': '' ); ?>">
<?php the_sub_field( 'tab_content' ); ?>
</div><!-- //.Tab -->
<?php $tab_count++; ?>
<?php endwhile; ?>
</div><!-- //.Tabs -->
<?php endif; ?>
Twig
<div class="Tabs">
<nav class="Tabs-nav">
{% for tab in post.get_field( 'tabs' ) %}
<a href="#" class="Tabs-link {{ (loop.first) ? 'is-active' : '' }}">{{tab.tab_title}}</a>
{% endfor %}
</nav><!-- //.Tabs-nav -->
{% for tab in post.get_field( 'tabs' ) %}
<div class="Tab {{ (loop.first) ? 'is-active' : '' }}">
{{tab.tab_content}}
</div><!-- //.Tab -->
{% endfor %}
</div><!-- //.Tabs -->
Styles
CSS
.Tabs-link {
background: #f9f9f9;
color: #ccc;
display: inline-block;
padding: 10px 15px;
text-decoration: none;
transition: all 0.3s ease-in-out;
}
.Tabs-link:hover,
.Tabs-link.is-active {
background: #eee;
color: #222;
}
.Tab {
border: 2px solid #eee;
display: none;
padding: 30px 15px;
}
.Tab.is-active {
display: block;
}
Sass
.Tabs-link {
background: #f9f9f9;
color: #ccc;
display: inline-block;
padding: 10px 15px;
text-decoration: none;
transition: all 0.3s ease-in-out;
&:hover,
&.is-active {
background: #eee;
color: #222;
}
}
.Tab {
border: 2px solid #eee;
display: none;
padding: 30px 15px;
&.is-active {
display: block;
}
}
Javascript
Plugin
/**
* Objectiv Tabs
*
*/
( function() {
'use strict';
// Let's make sure that we have an Objectiv object
if ( 'object' !== typeof window.Objectiv) {
window.Objectiv = {};
}
window.Objectiv.tabs = function(options) {
// Make sure that a target is passed into the options object
if ('undefined' === typeof options.target)
return false;
// Set up the variables
var tabs = document.querySelector(options.target),
tabLinks = tabs.getElementsByClassName('Tabs-link'),
tabContainers = tabs.getElementsByClassName('Tab'),
activeIndex = 0;
// If we don't have tabs, jump out
if (!tabs) return;
// Click handler function to go to tab on click
function tabClickHandler(link, index) {
link.addEventListener('click', function(e) {
e.preventDefault();
goToTab(index);
});
}
// Add appropriate classes based on the current index
function goToTab(index) {
if (index !== activeIndex && index >= 0 && index <= tabLinks.length) {
tabLinks[activeIndex].classList.remove('is-active');
tabLinks[index].classList.add('is-active');
tabContainers[activeIndex].classList.remove('is-active');
tabContainers[index].classList.add('is-active');
tabLinks[activeIndex].setAttribute( 'aria-selected', 'false' );
tabLinks[activeIndex].setAttribute( 'aria-expanded', 'false' );
tabContainers[activeIndex].setAttribute( 'aria-hidden', 'true' );
tabLinks[index].setAttribute( 'aria-selected', 'true' );
tabLinks[index].setAttribute( 'aria-expanded', 'true' );
tabContainers[index].setAttribute( 'aria-hidden', 'false' );
activeIndex = index;
}
}
// Loop through the links and set the clickhandler
Array.prototype.map.call(tabLinks, function(value, index) {
var link = value;
tabClickHandler(link, index);
if (link.classList.contains('is-active')) {
link.setAttribute( 'aria-selected', 'true' );
link.setAttribute( 'aria-expanded', 'true' );
}
});
// Loop through containers and add appropriate attributes
Array.prototype.map.call(tabContainers, function(value, index) {
var content = value;
content.setAttribute( 'role', 'tabpanel' );
if (content.classList.contains('is-active')) {
content.setAttribute( 'aria-hidden', 'false' );
} else {
content.setAttribute( 'aria-hidden', 'true' );
}
});
}
})();
Usage
Objectiv.tabs({
target: '.Tabs', // ID (or class) of accordion container
});