A tiny, fully accessible tab switcher for jQuery.
Useful for standard tabs and also 'hero' style tabs often found at the top of websites to display content.
https://codepen.io/simonsmith/full/wdYRva/
- Fade between tabs using CSS3 transitions with
.animate()
fallback - Tested with jQuery 1.12.0+
- Keyboard navigation
- WAI-ARIA (via http://www.accessibleculture.org/articles/2010/08/aria-tabs/)
- Focus on tab contents
- Touch events
- Flexible HTML
- Rotate tabs with a delay
It's recommended to require
/import
the plugin as part of an existing webpack or browserify setup:
npm install jquery jquery.herotabs --save
// index.js
const $ = require('jquery');
require('jquery.herotabs');
$('#tabs').herotabs();
Herotabs relies on jQuery as a peerDependency
so ensure it is installed in
your application.
Clone the repository and run npm install && npm run build
. This will generate
a UMD version of the plugin in ./build
that can be dropped into a project
however you want.
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="jquery.herotabs.js"></script>
$('.tabs').herotabs({
// options
});
A simple example of markup.
<div class="tabs">
<ul class="js-herotabs-nav">
<li class="js-herotabs-nav-item"><a href="#tab1">Item 1</a></li>
<li class="js-herotabs-nav-item"><a href="#tab2">Item 2</a></li>
<li class="js-herotabs-nav-item"><a href="#tab3">Item 3</a></li>
</ul>
<div class="js-herotabs-tab" id="tab1">
<p>content 1</p>
</div>
<div class="js-herotabs-tab" id="tab2">
<p>content 2</p>
</div>
<div class="js-herotabs-tab" id="tab3">
<p>content 3</p>
</div>
</div>
Herotabs depends on classnames rather than a specific structure so feel free to nest and shuffle your HTML as necessary. JS prefixed classnames are the default, but are not compulsory.
The only expectation it has is that your tab navigation will be contained by an element structure like the following:
<ul class="js-herotabs-nav">
<li class="js-herotabs-nav-item"><a href="#tab1">Item 1</a></li>
<li class="js-herotabs-nav-item"><a href="#tab2">Item 2</a></li>
<li class="js-herotabs-nav-item"><a href="#tab3">Item 3</a></li>
</ul>
<div class="js-herotabs-nav">
<span class="js-herotabs-nav-item"><a href="#tab1">Item 1</a></span>
<span class="js-herotabs-nav-item"><a href="#tab2">Item 2</a></span>
<span class="js-herotabs-nav-item"><a href="#tab3">Item 3</a></span>
</div>
Note Your navigation anchors must link to the tab content IDs (tab behaviour), or be fully-qualified URLs (follow link behaviour).
- delay - (number) How long between each tab change. If set to 0 no timed change will happen default
0
- duration - (number) If set to greater than zero, then this will decide how long it takes to fade transition between tabs otherwise it will be instant default
0
- easing - (string) Easing type, works only with CSS3 capable browsers default
ease-in-out
- startOn - (number) Index of the tab to show first default
0
- reverse - (boolean) Will reverse display order of tabs when on a timed delay default
false
- interactEvent - (string) Event to interact with the tab navigation. Possible values are
click
orhover
defaultclick
- useTouch - (boolean) - If the browser supports touch then Herotabs will try to use it instead of the
interactEvent
above defaulttrue
- useKeys - (boolean) - Attach key events default
true
- onReady - (function) - Called when the plugin has successfully instantiated. default
null
- onSetup - (function) - Called before the plugin has begun grabbing elements, setting up events etc. default
null
- css (object) Classes applied to the HTML structure
- active (string) - Added to the container when the plugin has setup default
is-active
- current (string) - Added to the current visible tab panel default
is-current-pane
- navCurrent (string) - Added to current visible nav item default
is-current-nav
- navId (string) - id to add to each nav link. Becomes
herotabs1
,herotabs2
etc defaultherotabs
- active (string) - Added to the container when the plugin has setup default
- selectors (object) - CSS selectors to grab the HTML
- tab (string) The tab panel containing the content default
.js-herotabs-tab
- nav (string) The nav container default
.js-herotabs-nav
- navItem (string) Each navigation item default
.js-herotabs-nav-item
- tab (string) The tab panel containing the content default
- zIndex (object) z-index values applied to the tabs
- bottom (number) Applied to all tabs default
1
- top (number) Applied to the currently visible tab default
2
- bottom (number) Applied to all tabs default
If you have multiple instances of Herotabs on one page then defaults used by all of them can be accessed via $.fn.herotabs.defaults
:
$.fn.herotabs.defaults.css.current = 'this-is-the-current-class';
// Create some instances
$('.tabs').herotabs();
$('.other-tabs').herotabs();
// Both will use `this-is-the-current-class`
Herotabs fires various events that you can listen to. They are fired off the element that herotabs
is instantiated on.
const $tabs = $('.tabs').herotabs();
$tabs.on('herotabs.show', function() {
// Do something when the tab shows!
});
$tabs.on('herotabs.show', function() {
// Do something else when the tab has shown!
});
Every event handler receives the jQuery event object and also the current visible tab, the index and the current selected nav item.
- tab - (jQuery object) The currently visible tab
- index - (number) The index of the currently visible tab
- nav - (jQuery object) The current selected nav item
var $tabs = $('.tabs').herotabs();
$tabs.on('herotabs.show', function(event, $tab, $index, $nav) {
$tab.addClass('currently-visible-tab');
$('body').text('The current tab index is ' + $index);
$nav.text('I am the current nav element');
});
Fired when a tab is shown
Fired when the current tab is hidden
Fired when the next tab is shown
Fired when the previous tab is shown
Fired after the tabs have begun cycling on a timed delay
Fired after the tabs have stopped cycling
Fired when the mouse enters the container of the tabs
Fired when the mouse leaves the container of the tabs
You can get at the Herotabs instance by accessing it from the elements .data
method
const instance = $('.tabs').herotabs().data('herotabs');
instance.nextTab();
Shows a tab. Accepts a zero based index or a jQuery element
instance.showTab(2) // Index
instance.showTab($('.js-herotabs-tab').eq(1)) // jQuery element
Shows the next tab. If the current tab is the last in the set it will show the first.
instance.nextTab()
Shows the previous tab. If the current tab is the first in the set it will show the last.
instance.prevTab()
If a delay is set in the options, then it will begin cycling through the tabs.
instance.start()
If the tabs are currently cycling, it will stop them
instance.stop()
Manually invoke a Herotabs event. Accepts an event name and jQuery object/index
instance.triggerEvent('herotabs.show', 2); // Use an index
instance.triggerEvent('herotabs.show', $('.a-single-tab')); // Or a jQuery object
Due to the events being attached after the plugin has initialised, this method might be useful if you have events that need to fire immediately or from somewhere else.
All methods return the instance so you can chain as many calls as you wish
instance.showTab(2).nextTab().nextTab();
If for any reason you need to override or add your own methods then you can access the Herotabs prototype before initialising it:
const Herotabs = $.fn.herotabs.Herotabs;
Herotabs.prototype.newMethod = function() {
// Something new!
};
const instance = $('.tabs').herotabs().data('herotabs');
instance.newMethod();
const Herotabs = require('jquery.herotabs');
Herotabs.prototype.newMethod = function() {
// Something new!
};
var instance = $('.tabs').herotabs().data('herotabs');
instance.newMethod();
$('.tabs')
.herotabs({
useTouch: false,
duration: 400,
interactEvent: 'hover',
selectors: {
tab: '.tab-panel',
navItem: '.tab-nav-item',
nav: '.tab-nav-container'
},
onSetup: function() {
// Do some setup work here
// e.g. generate some markup dynamically for Herotabs to attach to
}
})
.on('herotabs.show', function(event, $tab) {
$tab.text('You are looking at a tab!');
});
If you find a bug or need a feature added, please open an issue first.
npm install
npm test