jojoTabs is a jQuery plugin for responsive and accessible tabs that leverages ARIA roles, States and Properties
A Pen by Joe Watkins on CodePen.
<h1>jojoTabs.js<span>Easy Responsive & Accessible Tabs</h1> | |
<ul role="tablist"> | |
<li id="tab_1" aria-controls="panel_1" aria-selected="true" role="tab">Tab 1</li> | |
<li id="tab_2" aria-controls="panel_2" role="tab">Tab 2</li> | |
<li id="tab_3" aria-controls="panel_3" role="tab">Tab 3</li> | |
<li id="tab_4" aria-controls="panel_4" role="tab">Tab 4</li> | |
</ul> | |
<div id="panel_1" aria-labelledby="tab_1" aria-hidden="false" role="tabpanel"> | |
<h2>Tabbed Content 1</h2> | |
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
</div> | |
<div id="panel_2" aria-labelledby="tab_2" aria-hidden="true" role="tabpanel"> | |
<h2>Tabbed Content 2</h2> | |
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
</div> | |
<div id="panel_3" aria-labelledby="tab_3" aria-hidden="true" role="tabpanel"> | |
<h2>Tabbed Content 3</h2> | |
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
</div> | |
<div id="panel_4" aria-labelledby="tab_4" aria-hidden="true" role="tabpanel"> | |
<h2>Tabbed Content 4</h2> | |
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
</div> |
jojoTabs is a jQuery plugin for responsive and accessible tabs that leverages ARIA roles, States and Properties
A Pen by Joe Watkins on CodePen.
/*! | |
* jojoTabs.js | |
* Author: Joe Watkins - joe-watkins.io | |
* Licensed under the MIT license | |
* | |
*/ | |
(function($){ | |
$.fn.jojoTabs = function(options) { | |
var defaults = { | |
wrapper: this, | |
tab: '[role="tablist"] li', | |
tabPanel: '[role="tabpanel"]', | |
breakPoint: 768, | |
tabActiveClass: 'on', | |
smallScreenClass: 'small-screen-tabs', | |
tabPanelHiddenClass: 'visually-hidden', | |
smallScreenScroll: true, | |
smallScreenScrollSpeed : 400 | |
} | |
var options = $.extend(defaults, options); | |
var o = options; | |
var $tab = o.wrapper.find(o.tab), | |
$tabPanel = o.wrapper.find(o.tabPanel), | |
$breakPoint = o.breakPoint, | |
tabActiveClass = o.tabActiveClass, | |
smallScreenClass = o.smallScreenClass, | |
tabPanelHiddenClass = o.tabPanelHiddenClass; | |
// active class to first tab | |
$tab.eq(0).addClass(tabActiveClass); | |
// visually hide each tab panel | |
$tabPanel.not(':first').addClass(tabPanelHiddenClass); | |
$tab.each(function(index,element){ | |
var $tabTrigger = $(this), | |
tabPosition = index; | |
$tabTrigger.click(function(e){ | |
e.preventDefault(); | |
$tab.removeClass(tabActiveClass).attr('aria-selected','false'); | |
$(this).addClass(tabActiveClass).attr('aria-selected','true'); | |
$tabPanel.addClass(tabPanelHiddenClass); | |
$tabPanel.attr('aria-hidden','true'); | |
$tabPanel.each(function(index,element){ | |
var tabPanelPosition = index; | |
if(tabPosition == tabPanelPosition){ | |
$(this).removeClass(tabPanelHiddenClass); | |
$(this).attr('aria-hidden','false'); | |
if(_smallScreenCheck()){ | |
_scrollTop(tabPanelPosition,o.smallScreenScroll,o.smallScreenScrollSpeed); | |
} | |
} | |
}); | |
}); | |
}); | |
function _scrollTop(position,smallScreenScroll,smallScreenScrollSpeed){ | |
if(smallScreenScroll){ | |
$("html,body").animate({scrollTop: $tabPanel.eq(position).offset().top},smallScreenScrollSpeed); | |
}else{ | |
$(window).scrollTop($tabPanel.eq(position).offset().top); | |
} | |
} | |
function _smallScreenCheck(){ | |
if($('.'+smallScreenClass).size() === 1){ | |
return true; | |
} | |
} | |
function _handleResize(namedFunction,time){ | |
window.onresize = function(event) { | |
clearTimeout(this.id); | |
this.id = setTimeout(namedFunction, time); | |
} | |
} | |
function _addSmallScreenClass(){ | |
if($(window).innerWidth() < $breakPoint){ | |
$('body').addClass(smallScreenClass); | |
}else{ | |
$('body').removeClass(smallScreenClass); | |
} | |
} | |
// add small scree class if needed | |
_addSmallScreenClass(); | |
_handleResize(_addSmallScreenClass,500); // resize | |
}; // $.fn | |
}(jQuery)); | |
$('body').jojoTabs({ | |
animate : true, | |
breakPoint : 768, | |
tabActiveClass : 'on', | |
tabPanelHiddenClass : 'visually-hidden', | |
smallScreenScroll : true, | |
smallScreenScrollSpeed : 400 | |
}); |
@import "compass"; | |
$breakpoint: 48em; | |
[role="tablist"]{ | |
margin: 0; | |
padding: 0; | |
width: 100%; | |
overflow: hidden; | |
position: relative; | |
li { | |
list-style: none; | |
margin: 0 0 .3em 0; | |
line-height: 1.3em; | |
padding: .4em; | |
background: lighten(black, 80%); | |
color: black; | |
text-decoration: none; | |
cursor:pointer; | |
@media(min-width:$breakpoint){ | |
width: 17%; | |
margin: 0 .3em 0 0; | |
float: left; | |
} | |
&.on { | |
background: lighten(black, 70%);; | |
} | |
} | |
} | |
[role="tabpanel"]{ | |
background: lighten(black, 70%); | |
padding:1.3em; | |
} | |
.visually-hidden { | |
position: absolute; | |
overflow: hidden; | |
clip: rect(0 0 0 0); | |
height: 1px; width: 1px; | |
margin: -1px; padding: 0; border: 0; | |
} | |
body { | |
max-width:70%; | |
margin:1em auto; | |
padding:0 2em; | |
font-family: 'Open Sans', sans-serif; | |
background:#eee; | |
} | |
h1 span { | |
display:block; | |
font-size:70%; | |
color:lighten(black,20%); | |
} | |
h2 { | |
margin:0px; | |
} |